Schnelles Vorzeichen der Ganzzahl in C

7

Es gibt eine Zeichenfunktion in C:

%Vor%

Leider Vergleich Kosten sehr hoch, so muß ich Funktion reduzieren, um die Anzahl der Vergleiche ändern.

Ich habe Folgendes versucht:

%Vor%

In diesem Fall bekomme ich nur einen Vergleich.

Gibt es überhaupt einen Weg, Vergleiche zu vermeiden?

Bearbeiten möglich duplizieren keine Antwort auf eine Frage geben, wie alle Antworten C ++ sind, verwendet Vergleich (die ich vermeiden sollte) oder nicht zurück -1 , +1 , 0 .

    
Alex 29.01.2013, 09:47
quelle

5 Antworten

27

Zunächst einmal ist der ganzzahlige Vergleich sehr billig. Es ist Verzweigung , die (wegen der Gefahr von Verzweigungsfehlvorhersagen) kann teuer werden.

Ich habe Ihre Funktion auf einer Sandy-Bridge-Box mit gcc 4.7.2, gebenchmarkt und es dauert etwa 1.2ns pro Anruf.

Das Folgende ist etwa 25% schneller, bei etwa 0,9ns pro Anruf:

%Vor%

Der Maschinencode für das Obige ist vollständig zweiglos:

%Vor%

Zwei Dinge sind erwähnenswert:

  1. Das Grundlevel der Leistung ist sehr hoch.
  2. Die Beseitigung von Verzweigungen verbessert hier die Leistung, aber nicht dramatisch.
NPE 30.01.2013, 20:21
quelle
3
%Vor%

Der erste Teil ( x>>32 ) gibt -1 für negative Zahlen und 0 für 0 oder positive Zahlen. Der zweite Teil gibt Ihnen 1 wenn x & gt; 0 oder gleich INT_MIN und ansonsten 0. Oder gibt Ihnen die richtige endgültige Antwort.

Es gibt auch das kanonische return (x > 0) - (x < 0); , aber leider verwenden die meisten Compiler Zweige, um Code dafür zu generieren, obwohl es keine sichtbaren Zweige gibt. Sie können versuchen, es manuell in einen Zweiglosen Code umzuwandeln:

%Vor%

was wohl besser als das obige ist, da es nicht vom implementierungsdefinierten Verhalten abhängt, aber einen kleinen Fehler hat, weil es 0 für INT_MIN zurückgibt.

    
Chris Dodd 30.01.2013 19:48
quelle
2
%Vor%     
Bruce 07.08.2013 11:50
quelle
0

Wenn s(x) eine Funktion ist, die das Vorzeichen-Bit von x zurückgibt (Sie haben es durch ((unsigned int)x)>>31 implementiert), können Sie s(x) und s(-x) irgendwie kombinieren. Hier ist eine "Wahrheitstabelle":

  

x & gt; 0: s (x) = 0; s (-x) = 1; Ihre Funktion muss 1

zurückgeben      

x & lt; 0: s (x) = 1; s (-x) = 0; Ihre Funktion muss -1

zurückgeben      

x = 0: s (x) = 0; s (-x) = 0; Ihre Funktion muss 0 zurückgeben

So können Sie sie auf folgende Weise kombinieren:

%Vor%     
anatolyg 30.01.2013 19:47
quelle
-1
%Vor%     
Aniket Inge 30.01.2013 19:44
quelle

Tags und Links