Zusammenfassung:
Ich suche den schnellsten Weg, um zu berechnen
(int) x / (int) y
ohne eine Ausnahme zu bekommen für y==0
. Stattdessen möchte ich nur ein beliebiges Ergebnis.
Hintergrund:
Beim Codieren von Bildverarbeitungsalgorithmen muss ich oft durch einen (akkumulierten) Alpha-Wert dividieren. Die einfachste Variante ist einfacher C-Code mit ganzzahliger Arithmetik. Mein Problem ist, dass ich für Ergebnispixel mit normalerweise einen Fehler durch Division durch Null erhalte alpha==0
. Dies sind jedoch genau die Pixel, bei denen das Ergebnis überhaupt keine Rolle spielt: Ich interessiere mich nicht für Farbwerte von Pixeln mit alpha==0
.
Einzelheiten:
Ich suche so etwas wie:
result = (y==0)? 0 : x/y;
oder
result = x / MAX( y, 1 );
x und y sind positive ganze Zahlen. Der Code wird sehr oft in einer verschachtelten Schleife ausgeführt, daher suche ich nach einer Möglichkeit, die bedingte Verzweigung zu beseitigen.
Wenn y den Bytebereich nicht überschreitet, bin ich mit der Lösung zufrieden
unsigned char kill_zero_table[256] = { 1, 1, 2, 3, 4, 5, 6, 7, [...] 255 };
[...]
result = x / kill_zero_table[y];
Dies funktioniert jedoch offensichtlich nicht gut für größere Reichweiten.
Ich denke, die letzte Frage ist: Was ist der schnellste Bit-Twiddling-Hack, der 0 in einen anderen ganzzahligen Wert ändert, während alle anderen Werte unverändert bleiben?
Klarstellungen
Ich bin mir nicht 100% sicher, dass die Verzweigung zu teuer ist. Es werden jedoch unterschiedliche Compiler verwendet, daher bevorzuge ich Benchmarking mit geringen Optimierungen (was in der Tat fraglich ist).
Natürlich sind Compiler großartig, wenn es um Bit-Twiddling geht, aber ich kann das Ergebnis "egal" in C nicht ausdrücken, sodass der Compiler niemals alle Optimierungen nutzen kann.
Der Code sollte vollständig C-kompatibel sein. Die Hauptplattformen sind Linux 64 Bit mit gcc & clang und MacOS.
y += !y
? Kein Zweig benötigt, um das zu berechnen. Sie könnten vergleichen x / (y + !y)
gegen x / max(y, 1)
und vielleicht auch y ? (x/y) : 0
. Ich denke, es wird in keinem von beiden einen Zweig geben, zumindest wenn die Optimierungen aktiviert sind.
0
Abschnitte groß und zusammenhängend sind. Es gibt einen Ort, an dem man mit Mikrooptimierungen herumspielen kann, und Operationen pro Pixel sind genau dieser Ort.