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
constchar*f1(longlongfoo)
2
{
3
returnfoo<0x1234000000000000ll?"low":"high";
4
}
5
constchar*f2(longlongfoo)
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.
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
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.
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?
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.
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.
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.