So vermeiden Sie die Verzweigung in C für diese Operation

7

Gibt es eine Möglichkeit, die folgende if-Anweisung zu entfernen, um zu überprüfen, ob der Wert unter 0 liegt?

%Vor%

Der Wert von c sollte zwischen 0 und 3600 liegen. Sowohl a als auch b sind signiert. Der Wert von a sollte auch zwischen 0 und 3600 liegen. (Ja, es ist ein Zählwert in 0,1 Grad). Der Wert wird durch einen Interrupt auf 3600 zurückgesetzt, aber wenn dieser Interrupt zu spät kommt, wird er unterlaufen, was kein Problem ist, aber die Software sollte trotzdem in der Lage sein, damit umzugehen. Was es tut.

Wir machen das if (c < 0) an einigen Stellen, an denen wir Positionen berechnen. (Berechnung einer neuen Position usw.)

Ich war an den Python-Modulo-Operator gewöhnt, um die Signedness des Divisors zu verwenden, wo unser Compiler (C89) die Dividend-Signedness verwendet.

Gibt es eine Möglichkeit, diese Berechnung anders durchzuführen? Beispiel Ergebnisse:

%Vor%     
Daan Timmer 19.07.2013, 14:43
quelle

5 Antworten

12

Gute Frage! Wie wäre es damit?

%Vor%

Dies ist eine Möglichkeit, die Verzweigungsvorhersager-Slots zu erhalten.

    
jman 19.07.2013, 15:37
quelle
7

Was ist das (angenommen 32-Bit-Ints):

%Vor%

c >> 31 setzt alle Bits auf das ursprüngliche MSB, was 1 für negative Zahlen und 0 für andere in 2-Komplement ist.

Negative Zahlenverschiebung rechts ist formal implementation-defined nach C-Standard-Dokumenten, aber es ist fast immer mit MSB-Kopieren implementiert (gemeinsame Prozessoren können es in einem einzigen Befehl tun).

Dies wird sicherlich zu keinen Zweigen führen, im Gegensatz zu (c < 0) , das in einigen Fällen mit Verzweigungen implementiert werden kann.

    
zch 19.07.2013 21:13
quelle
5

Warum machen Sie sich Sorgen wegen der Branche? [Grund in Kommentaren zu der Frage erklärt.]

Die Alternative ist etwas wie:

%Vor%

Dies setzt voraus, dass a und b bereits im Bereich 0..3600 liegen; Wenn sie nicht unter Kontrolle sind, ist die allgemeinere Lösung diejenige, die Drew McGowen vorschlage :

%Vor%

Der Verzweigungsfehler muss sehr teuer sein, um so viele Berechnungen lohnend zu machen.

    
Jonathan Leffler 19.07.2013 15:29
quelle
4

@skjaidev zeigte, wie man es ohne Verzweigung macht. So vermeiden Sie die Multiplikation automatisch, wenn int s Zweierkomplement ist:

%Vor%     
Olathe 19.07.2013 20:49
quelle
0

Was Sie tun möchten, ist modulare Arithmetik. Ihre Zweierkomplement-Maschine macht dies bereits mit ganzzahliger Mathematik. Also, indem Sie Ihre Werte in Zweierkomplementarithmetik abbilden, können Sie die modolo-Operation frei bekommen.

Der Trick besteht darin, Ihren Winkel als einen Bruchteil von 360 Grad zwischen 0 und 1-Epsilon darzustellen. Natürlich müssten dann deine konstanten Winkel ähnlich dargestellt werden, aber das sollte nicht schwer sein; Es ist nur ein bisschen Mathematik, die wir in einer Konvertierungsfunktion (äh, Makro) verstecken können.

Der Wert in dieser Idee ist, dass Sie, wenn Sie Winkel addieren oder subtrahieren, einen Wert erhalten, dessen Bruchteil Sie wollen und dessen ganzer Teil Sie wegwerfen möchten. Wenn wir den Bruch als eine 32-Bit-Festkommazahl mit dem Binärpunkt bei 2 ^ 32 darstellen (z. B. links von dem, was normalerweise als Vorzeichenbit angesehen wird), fallen Überläufe des Bruches einfach von der Spitze des 32-Bit-Wert kostenlos. Also, Sie tun alle Integer-Mathematik, und "Überlauf" Entfernung geschieht kostenlos.

Also würde ich Ihren Code (unter Beibehaltung der Idee von Grad mal 10) neu schreiben:

%Vor%

Ich habe diesen Code nicht kompiliert und ausgeführt.

Änderungen, um diesen Grad mal 100 oder mal 1 zu machen, sind ziemlich einfach; Modifizieren Sie den angle_scale_factor. Wenn Sie eine 16-Bit-Maschine haben, ist das Umschalten auf 16 Bit ähnlich einfach; Wenn Sie 32 Bit haben und immer noch nur 16 Bit rechnen wollen, müssen Sie den zu druckenden Wert auf 16 Bit maskieren.

Diese Lösung hat noch eine andere nette Eigenschaft: Sie haben dokumentiert, welche Variablen Winkel sind (und lustige Darstellungen haben). Der ursprüngliche Code von OP nannte sie nur ints, aber das ist nicht das, was sie darstellen; ein zukünftiger Betreuer wird von dem ursprünglichen Code überrascht sein, besonders wenn er die Subtraktion isoliert von den Variablen findet.

    
Ira Baxter 21.07.2013 04:50
quelle

Tags und Links