요약:
계산하는 가장 빠른 방법을 찾고 있습니다
(int) x / (int) y
예외없이 y==0
. 대신 임의의 결과를 원합니다.
배경:
이미지 처리 알고리즘을 코딩 할 때 종종 (누적 된) 알파 값으로 나눌 필요가 있습니다. 가장 간단한 변형은 정수 산술을 사용하는 일반 C 코드입니다. 내 문제는 일반적으로 결과 픽셀에 대해 0으로 나누기 오류가 발생한다는 것입니다 alpha==0
. 그러나 이것은 결과가 전혀 중요하지 않은 정확히 픽셀입니다. 나는 픽셀의 색상 값에 대해 신경 쓰지 않습니다 alpha==0
.
세부:
다음과 같은 것을 찾고 있습니다.
result = (y==0)? 0 : x/y;
또는
result = x / MAX( y, 1 );
x와 y는 양의 정수입니다. 코드는 중첩 루프에서 여러 번 실행되므로 조건부 분기를 제거하는 방법을 찾고 있습니다.
y가 바이트 범위를 초과하지 않으면 솔루션에 만족합니다.
unsigned char kill_zero_table[256] = { 1, 1, 2, 3, 4, 5, 6, 7, [...] 255 };
[...]
result = x / kill_zero_table[y];
그러나 이것은 분명히 더 큰 범위에서 잘 작동하지 않습니다.
마지막 질문은 다음과 같습니다. 0을 다른 정수 값으로 변경하고 다른 모든 값을 변경하지 않은 채로 변경하는 가장 빠른 비트 twiddling 해킹은 무엇입니까?
설명
나는 분기가 너무 비싸다고 100 % 확신하지 못합니다. 그러나 다른 컴파일러가 사용되므로 최적화가 거의없는 벤치마킹을 선호합니다 (실제로 의심 스럽습니다).
확실히 컴파일러는 비트 트위들 링에 관해서는 훌륭하지만 C로 "do n't care"결과를 표현할 수 없으므로 컴파일러는 전체 범위의 최적화를 사용할 수 없습니다.
코드는 완전히 C와 호환되어야하며 주요 플랫폼은 gcc 및 clang 및 MacOS가있는 Linux 64 비트입니다.
y += !y
? 그것을 계산하는 데 필요한 분기가 없습니다. 당신은 비교할 수 x / (y + !y)
에 대해 x / max(y, 1)
아마도하고 y ? (x/y) : 0
. 적어도 최적화가 켜져 있으면 둘 중 하나에 분기가 없을 것 같습니다.
0
섹션이 거대하고 연속적인 경우 현대 분기 예측이 허용됩니다 . 마이크로 최적화를 조작 할 수 있는 곳 이 있으며 픽셀 당 작업이 바로 그 곳입니다.