Ich habe diese C-Funktion:
%Vor%Ich rufe in einer engen Schleife an und möchte den Zweig loswerden, um zu sehen, ob er die Leistung verbessert.
Ich kann das nicht verwenden:
%Vor% weil es NaN
zurückgibt, wenn x == 0
(was ungefähr 25% der Zeit entspricht).
Gibt es eine andere Möglichkeit, es zu implementieren, so dass es 0
zurückgibt, wenn x == 0
, aber immer noch die Verzweigung loswerden?
(Ich bin weniger besorgt über negative Eingaben, weil diese Fehler sind, während Nullen nicht sind.)
Jeder freie Code für die Verzweigung muss eine Berechnung von x * log(x)
enthalten, um den "normalen" Fall abzudecken.
Bevor Sie also versuchen, diesen zweigfreien Code zu entwickeln, messen Sie die Geschwindigkeit von x * log(x)
allein. Sofern es nicht wesentlich schneller ist als der Code, den Sie haben, gibt es hier nichts Wesentliches. Und ich vermute, dass es nicht sein wird.
Beachten Sie zuerst, dass log (1) = 0 ist. Dann können Sie das Problem als x * log (y) schreiben, wobei y = 1, wenn x & lt; = 0, und ansonsten gleich x ist; Wenn y = 1, dann spielt x keine Rolle, weil log (y) = 0 ist.
Etwas wie y = (x & gt; 0) * x + (x & lt; = 0) wird dies tun, und dann:
%Vor%Es hängt nur davon ab, ob log (1) und vier ganzzahlige Ops schlechter sind als eine Verzweigung.
Compiler-Erweiterungen können hier helfen. In GCC würden Sie dies tun:
%Vor% GCC generiert dann Maschinencode, der den Zweig x > 0 == 1
bevorzugt.
Wenn Sie negative Zahlen nicht interessieren, können Sie stattdessen x == 0
als unwahrscheinlichen Zweig behandeln:
Wenn Sie nicht in GCC sind, sollten Sie die Dokumentation Ihres Compilers überprüfen und sehen, ob es eine analoge Funktion bietet.
Beachten Sie, dass es immer noch nicht zweigfrei ist. Es ist nur so, dass der wahrscheinliche Zweig weniger Zeit benötigt.
Tags und Links optimization c nan branch-prediction logarithm