Tóm lược:
Tôi đang tìm cách tính toán nhanh nhất
(int) x / (int) y
mà không nhận được một ngoại lệ cho y==0
. Thay vào đó tôi chỉ muốn một kết quả tùy ý.
Lý lịch:
Khi mã hóa các thuật toán xử lý hình ảnh, tôi thường cần chia cho một giá trị alpha (tích lũy). Biến thể đơn giản nhất là mã C thuần túy với số học nguyên. Vấn đề của tôi là tôi thường nhận được lỗi chia cho 0 đối với các pixel kết quả có alpha==0
. Tuy nhiên, đây chính xác là những pixel mà kết quả không quan trọng chút nào: Tôi không quan tâm đến giá trị màu của pixel với alpha==0
.
Chi tiết:
Tôi đang tìm kiếm một cái gì đó như:
result = (y==0)? 0 : x/y;
hoặc là
result = x / MAX( y, 1 );
x và y là các số nguyên dương. Mã được thực thi rất nhiều lần trong một vòng lặp lồng nhau, vì vậy tôi đang tìm cách loại bỏ phân nhánh có điều kiện.
Khi y không vượt quá phạm vi byte, tôi hài lòng với giải pháp
unsigned char kill_zero_table[256] = { 1, 1, 2, 3, 4, 5, 6, 7, [...] 255 };
[...]
result = x / kill_zero_table[y];
Nhưng điều này rõ ràng không hoạt động tốt cho các phạm vi lớn hơn.
Tôi đoán câu hỏi cuối cùng là: Đâu là cách hack twiddling bit nhanh nhất thay đổi 0 thành bất kỳ giá trị số nguyên nào khác, trong khi giữ nguyên tất cả các giá trị khác?
Làm rõ
Tôi không chắc chắn 100% rằng việc phân nhánh quá đắt. Tuy nhiên, các trình biên dịch khác nhau được sử dụng, vì vậy tôi thích đo điểm chuẩn với ít tối ưu hóa (điều này thực sự đáng nghi ngờ).
Chắc chắn, các trình biên dịch là tuyệt vời khi nói đến các bit twiddling, nhưng tôi không thể diễn đạt kết quả "don't care" trong C, vì vậy trình biên dịch sẽ không bao giờ có thể sử dụng đầy đủ các tối ưu hóa.
Mã phải tương thích hoàn toàn với C, nền tảng chính là Linux 64 Bit với gcc & clang và MacOS.
y += !y
gì? Không cần nhánh để tính toán điều đó. Bạn có thể so sánh x / (y + !y)
với x / max(y, 1)
và có thể cũng có y ? (x/y) : 0
. Tôi đoán sẽ không có chi nhánh nào ở cả hai, ít nhất là khi đã bật tối ưu hóa.
0
phần alpha rất lớn và liền nhau. Có một nơi để mày mò với các tối ưu hóa vi mô và hoạt động trên mỗi pixel chính xác là nơi đó.