Podsumowanie:
Szukam najszybszego sposobu obliczenia
(int) x / (int) y
bez wyjątku dla y==0
. Zamiast tego chcę po prostu arbitralnego wyniku.
Tło:
Podczas kodowania algorytmów przetwarzania obrazu często muszę podzielić przez (skumulowaną) wartość alfa. Najprostszym wariantem jest zwykły kod C z arytmetyką liczb całkowitych. Mój problem polega na tym, że zwykle otrzymuję błąd dzielenia przez zero dla pikseli wynikowych z alpha==0
. Jednak są to dokładnie piksele, w których wynik nie ma żadnego znaczenia: nie obchodzą mnie wartości kolorów pikseli z alpha==0
.
Detale:
Szukam czegoś takiego:
result = (y==0)? 0 : x/y;
lub
result = x / MAX( y, 1 );
x i y są dodatnimi liczbami całkowitymi. Kod jest wykonywany ogromną liczbę razy w zagnieżdżonej pętli, więc szukam sposobu na pozbycie się rozgałęzień warunkowych.
Kiedy y nie przekracza zakresu bajtów, jestem zadowolony z rozwiązania
unsigned char kill_zero_table[256] = { 1, 1, 2, 3, 4, 5, 6, 7, [...] 255 };
[...]
result = x / kill_zero_table[y];
Ale to oczywiście nie działa dobrze dla większych zakresów.
Wydaje mi się, że ostatnie pytanie brzmi: jaki jest najszybszy sposób na zmianę wartości 0 na dowolną inną liczbę całkowitą, pozostawiając wszystkie inne wartości bez zmian?
Wyjaśnienia
Nie jestem w 100% pewien, czy rozgałęzianie jest zbyt drogie. Jednak używane są różne kompilatory, więc wolę testy porównawcze z niewielkimi optymalizacjami (co jest rzeczywiście wątpliwe).
Z pewnością kompilatory są świetne, jeśli chodzi o manipulowanie bitami, ale nie mogę wyrazić wyniku "nie przejmuję się" w C, więc kompilator nigdy nie będzie w stanie wykorzystać pełnego zakresu optymalizacji.
Kod powinien być w pełni kompatybilny z C, główne platformy to Linux 64-bitowy z gcc i clang oraz MacOS.
y += !y
? Żadna gałąź nie była potrzebna do obliczenia tego. Możesz porównać x / (y + !y)
z, x / max(y, 1)
a może także y ? (x/y) : 0
. Myślę, że w żadnym z nich nie będzie odgałęzienia, przynajmniej przy włączonych optymalizacjach.
0
sekcje alfa są duże i ciągłe. Jest miejsce na majstrowanie przy mikrooptymalizacjach, a operacje na piksel są właśnie tym miejscem.