Verzweigungsfreie Implementierung von f (x): = wenn x == 0 dann 0 else (x * log (x))

7

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.)

    
finnw 15.11.2012, 17:54
quelle

3 Antworten

7

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.

    
Steve Jessop 15.11.2012, 21:10
quelle
13

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.

    
Hodapp 15.11.2012 18:20
quelle
11

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:

%Vor%

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.

    
Nikos C. 15.11.2012 18:02
quelle