Hi, ich hab eine signed long long int Variable in meinem Programm. Für einen if Vergleich <= und >= möchte ich zeitsparend nur auf das obere 32 Bit-Wort zugreifen. Wie sag ich das meinem Compiler (Realview) ?
So etwas zu "optimieren" ist bei aktuellen Compilern meist Zeitverschwendung ;-)
1 | const char *f1(long long foo) |
2 | {
|
3 | return foo < 0x1234000000000000ll ? "low" : "high"; |
4 | }
|
5 | const char *f2(long long foo) |
6 | {
|
7 | return (long)(foo >> 32) < 0x12340000 ? "low" : "high"; |
8 | }
|
Gcc (x86/32) erzeugt für f1 und f2 exakt den gleichen Code (mit -O; ohne Optimizer ist f1 besser). Was der Realview daraus macht, musst du selbst testen...
Daumenregel: Wenn man mehr Zeit in die manuelle Optimierung und entsprechend komplexere Pflege eines Programms reinsteckt, als man kumuliert zur Laufzeit wieder rausholt, dann ist man schwer auf dem Holzweg.
:
Bearbeitet durch User
foobar schrieb: > mit -O; ohne Optimizer ist f1 besser Ich hätte aus dem Bauch heraus gesagt f2 ist besser!
Und hier (gcc 4.2) ist f1 besser, mit -O2: .f1: lis 0,0x1233 ori 0,0,65535 cmpw 7,3,0 ble 7,L..8 lwz 9,LC..1(2) addi 3,9,4 blr .f2: lis 0,0x1233 srawi 9,3,31 srawi 10,3,0 ori 0,0,65535 cmpw 7,10,0 bgt 7,L..10 lwz 3,LC..3(2) blr
foobar schrieb: > foo >> 32 Für foo < 0 ist das implementation defined. Du musst also erst die Realview-Spezifikation wälzen, um herauszufinden, ob es das machst, was du erwartest.
Jetzt mal ganz offen gefragt: Warum? Ok, der 64-Bit-Vergelich braucht eventuell ein paar Zyklen mehr, als der 32-Bit-Vergleich,aber jede Umwandlung kostet auch Zeit. Kommt es da wirklich drauf an? Oliver
Oliver S. schrieb: > Jetzt mal ganz offen gefragt: Warum? Wegen
1 | const char *f2(long long foo) |
wenn da "unsigned long long" stehen würde, würde es anders aussehen. In aller Kürze: wenn man auf Nummer sicher gehen will, dann benutzt man zum Bitpfriemeln immer unsigned Datentypen. Nur für die ist das Verhalten auf Bitebene exakt definiert.
:
Bearbeitet durch User
Du könntest die long long zusammen mit einem int array[2] in ein union packen. Achtung, auf die Endianness achten.
Schwimmbadpinkler schrieb: > möchte ich zeitsparend nur auf das obere 32 > Bit-Wort zugreifen Die Zeitersparnis für dafür dürfte kleiner als der Zeitaufwand für diesen Post hier sein.
Schwimmbadpinkler schrieb: > Für einen if Vergleich <= und >= möchte ich zeitsparend nur auf das obere > 32 Bit-Wort zugreifen. Wenn sich überhaupt eine Ersparnins daraus ergeben sollte, wird diese minimal ausfallen. Wieviele Millionen solcher Vergleiche muss dein µC denn pro Sekunde machen, daß das so wichtig ist?
Der uC macht 500000 solcher Vergleiche pro Sekunde. F-CPU = 41.779200MHz
Schwimmbadpinkler schrieb: > Der uC macht 500000 solcher Vergleiche pro Sekunde. F-CPU = > 41.779200MHz Macht er die wirklich, oder schafft er die rechnerisch?
Matthias Lipinsky schrieb: > Macht er die wirklich, oder schafft er die rechnerisch? Da will ich hinkommen, das er das schafft. Um jeden Taktzyklus kämpfen...
Schwimmbadpinkler schrieb: > Da will ich hinkommen, das er das schafft. Um jeden Taktzyklus > kämpfen... Ich sehe da vier Möglichkeiten (in genau dieser Reihenfolge): 1. Den Verwendeten Algorithmus optimieren (nein, nicht den Vergleich, sondern die Dinge die eine oder mehrere Ebenen darüber liegen). 2. Einen Controller mit mehr Bumms verwenden. 3. Die zeitkritischen Dinge von Hand in Assembler programmieren. 4. Stunden damit verbringen Mikrooptimierungen auf C-Ebene durchzuführen, die mit der nächsten Compilerversion vermutlich alle über den Haufen geworfen werden.
foobar schrieb: > const char *f2(long long foo) > { > return (long)(foo >> 32) < 0x12340000 ? "low" : "high"; > } Was macht das "low" bzw. "high"?
TriHexagon schrieb: > http://msdn.microsoft.com/de-de/library/ty67wk28.aspx > Operator ?: (C#-Referenz) Facepalm.
Schwimmbadpinkler schrieb: > foobar schrieb: >> const char *f2(long long foo) >> { >> return (long)(foo >> 32) < 0x12340000 ? "low" : "high"; >> } > > Was macht das "low" bzw. "high"? Für das Ergebnis des Vergleichs. Irgendwas muss ja passieren, wenn die Zahl kleiner bzw. größer/gleich ist. foobar hat halt einfach was erfunden. Das du das nicht erkennst, lässt deine Aussage, dass du um jeden Taktzyklus kämpfst in einem ganz neuen Licht dastehen. Wieder einer der denkt, man könne mit derartigen Mikrooptimierungen (die für die meisten Compiler nicht mehr als eine Fingerübung darstellen) ein zu lahmes Programm retten.
:
Bearbeitet durch User
So: ((long*)(&value1)[1]<=0x12341234)?1:0; für [x] musst du noch wissen, ob der Controller little oder big endian verwendet. @foobar: Das ist furchtbar. Da merkt man den PC-Hacker.
Schwimmbadpinkler schrieb: > Matthias Lipinsky schrieb: >> Macht er die wirklich, oder schafft er die rechnerisch? > > Da will ich hinkommen, das er das schafft. Um jeden Taktzyklus > kämpfen... Aber hoffentlich erst, nachdem Du ein vollständiges Programm entwickelt hast, welches für all Deine Anwendungsfälle korrekte Ergebnisse liefert. Wenn ein solches Programm schnell genug läuft, dann vergiss das "um jeden Taktzyklus kämpfen" lieber. Für nicht genutzte Rechenzeit gibt es kein Geld zurück.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.