Resumo:
Estou procurando a maneira mais rápida de calcular
(int) x / (int) y
sem obter uma exceção para y==0
. Em vez disso, quero apenas um resultado arbitrário.
Fundo:
Ao codificar algoritmos de processamento de imagem, geralmente preciso dividir por um valor alfa (acumulado). A variante mais simples é o código C simples com aritmética de inteiros. Meu problema é que normalmente obtenho uma divisão por erro zero para pixels de resultado com alpha==0
. No entanto, estes são exatamente os pixels em que o resultado não importa em absoluto: Não me importo com os valores de cor dos pixels com alpha==0
.
Detalhes:
Estou procurando algo como:
result = (y==0)? 0 : x/y;
ou
result = x / MAX( y, 1 );
x e y são inteiros positivos. O código é executado um grande número de vezes em um loop aninhado, então estou procurando uma maneira de me livrar da ramificação condicional.
Quando y não excede o intervalo de bytes, fico feliz com a solução
unsigned char kill_zero_table[256] = { 1, 1, 2, 3, 4, 5, 6, 7, [...] 255 };
[...]
result = x / kill_zero_table[y];
Mas isso obviamente não funciona bem para intervalos maiores.
Eu acho que a pergunta final é: Qual é o hack de twiddling de bits mais rápido, alterando 0 para qualquer outro valor inteiro, enquanto deixa todos os outros valores inalterados?
Esclarecimentos
Não estou 100% certo de que a ramificação é muito cara. No entanto, diferentes compiladores são usados, então eu prefiro benchmarking com poucas otimizações (o que é realmente questionável).
Com certeza, os compiladores são ótimos quando se trata de manipulação de bits, mas não posso expressar o resultado "não me importo" em C, então o compilador nunca será capaz de usar toda a gama de otimizações.
O código deve ser totalmente compatível com C, as plataformas principais são Linux 64 bits com gcc & clang e MacOS.
y += !y
? Nenhum ramo necessário para computar isso. Você poderia comparar x / (y + !y)
contra x / max(y, 1)
e talvez também y ? (x/y) : 0
. Acho que não haverá ramificação em nenhum deles, pelo menos com as otimizações ativadas.
0
seções alfa forem enormes e contíguas. Existe um lugar para brincar com micro otimizações, e operações por pixel é exatamente esse lugar.