Hallo.
Aufgrund dieses Postings, frage ich mich nun, welches der schnellste und effizienteste Befehl ist, um 1 dazuzuzählen oder abzuziehen.
Praxisbeispiel:
;Annahme: Eventloop einer GUI
Define.b Exit = 0 ;Exit-Variable
Repeat
Event = WaitWindowEvent(TimeOut)
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #BTN_Exit
;was nun hier?
!MOV byte [v_Exit], 1 ;oder
!ADD byte [v_Exit], 1 ;oder
!INC byte [v_Exit]
[...]
;Nach einer Abfrage, ob das Programm ohne Speichern beendet werden soll, und auf "Nein" gedrückt wird:
!MOV byte [v_Exit], 0 ;oder
!SUB byte [v_Exit], 1 ;oder
!DEC byte [v_Exit]
[...]
Until Exit
End
Grüße, Mok.
Win 7 Home Premium 64 bit | PureBasic 5.20 - x86 und x86-64 | Firefox [aktuelle stable-Version hier einfügen]
"Jeder macht irgendwann mal Fehler, darum gibt's auch Bleistifte mit Radiergummi." --Carl
lt. meiner Taktzyklentabelle aus Oliver Müller´s Assembler Referenz
benötigt
INC r/m32: 1 bzw. 3 Zyklen ebenso wie
ADD r/m32,imm32: 1 bzw. 3 Zyklen
(1 Zyklus bei Register und 3 Zyklen bei Verwendung Speicheradresse)
Bei DEC und SUB ist es das gleiche.
Ist also gleich schnell.
MOV r/m32,imm32 benötigt 1 Zyklus
r ist ein Register, m32 eine Speicheradresse und imm32 eine 32Bit Konstante.
Die Angaben sind vom Pentium I, neuere Prozessoren sind in meiner Tabelle leider nicht enthalten. Aber nachdem hier schon mal der gleiche Speed erreicht wird hoffe ich dass es sich auf neueren Prozessoren nicht verschlechtert. Auf älteren Prozessoren waren da mal Unterschiede zwischen INC und ADD bzw. DEC und SUB
Grüße
NicknameFJ
Zuletzt geändert von NicknameFJ am 28.07.2010 19:13, insgesamt 1-mal geändert.
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller
#anzahl = 100000000
a.i = 1
time = ElapsedMilliseconds()
For i = 0 To #anzahl-1
! ADD dword [v_a], 1
Next
time1 = ElapsedMilliseconds()-time
time = ElapsedMilliseconds()
For i = 0 To #anzahl-1
! INC dword [v_a]
Next
time2 = ElapsedMilliseconds()-time
MessageRequester("Info", Str(time1)+"/"+Str(time2))
@NicknameFJ: Und wie siehts aus mit CMP vs AND? Zumindest habe ich in PBs generierten ASM-Code gesehen, dass eher AND statt CMP genutzt wird.
Win 7 Home Premium 64 bit | PureBasic 5.20 - x86 und x86-64 | Firefox [aktuelle stable-Version hier einfügen]
"Jeder macht irgendwann mal Fehler, darum gibt's auch Bleistifte mit Radiergummi." --Carl
OK, bei mir auch. Hatte ich gesagt, weil ich mich zu erinnern glaube, dass add/sub auf einigen Prozessoren schneller sind (und auf anderen eben gleich schnell). /
Glück für mich, dass ich das „AFAIK“ so groß geschrieben hab.
PS: Wobei der gcc immer ein add/sub draus macht (auch wenn man ihm in C-Manier direkt eine Art inc/dec per ++/-- empfiehlt), und der im Allgemeinen so extrem optimiert, dass das eher kein Zufall ist. Aber da es wohl bei den meisten gleich schnell ist, ist das wohl nur nebenbei zu betrachten.
laut intel optimization guide sind inc und dec nicht mehr zu nutzen, da sie nicht länger von intel optimiert werden und bei neueren cpus langsamer sind.
generell beantworten kann man solche fragen nicht, da soetwas cpu model spezifisch ist. es gibt nicht nur unterschiede zwischen amd und intel cpu's sondern aich von generation zu generation.
Allerdings sind das sowieso minimale geschwindigkeitsunterschiede. Um die macht von assembler wirklich zu nutzen musst du deine denkweise an die cpu anpassen und extrem spezialisierten code schreiben. desdo generischer dein code ist, desdo geringer der geschwindigkeitsunterschied zu hochsprachencode.
Pack möglichst alle variablen in register um speicherzugriffe zu minimieren. minimiere die anzahl bedingter sprünge, nutze unrolling, berechne so viel du kannst vor und pack das in register für die eigentliche schleife, usw.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!
sind auf Pentium I gleich schnell. Einen Unterschied machen die beiden Befehle allerdings bei den Flags!
Beim Vergleich auf NULL ist jedoch in beiden Fällen das ZeroFlag gesetzt oder gelöscht sodass dies in diesem Fall nicht zum Tragen kommt.
Danke an Thorium für den interessanten Hinweis auf das Intel Optimization Guide
Dieser schreibt:
3.5.1.7 Compares
Use TEST when comparing a value in a register with zero. TEST essentially ANDs
operands together without writing to a destination register. TEST is preferred over
AND because AND produces an extra result register. TEST is better than CMP ..., 0
because the instruction size is smaller.
Use TEST when comparing the result of a logical AND with an immediate constant for
equality or inequality if the register is EAX for cases such as:
IF (AVAR &8) { }
The TEST instruction can also be used to detect rollover of modulo of a power of 2.
For example, the C code:
IF ( (AVAR % 16) == 0 ) { }
can be implemented using:
TEST EAX, 0x0F
JNZ AfterIf
Using the TEST instruction between the instruction that may modify part of the flag
register and the instruction that uses the flag register can also help prevent partial
flag register stall.
Assembly/Compiler Coding Rule 39. (ML impact, M generality) Use the TEST
instruction instead of AND when the result of the logical AND is not used. This saves
μops in execution. Use a TEST if a register with itself instead of a CMP of the register
to zero, this saves the need to encode the zero and saves encoding space. Avoid
comparing a constant to a memory operand. It is preferable to load the memory
operand and compare the constant to a register.
Often a produced value must be compared with zero, and then used in a branch.
Because most Intel architecture instructions set the condition codes as part of their
execution, the compare instruction may be eliminated. Thus the operation can be
tested directly by a JCC instruction. The notable exceptions are MOV and LEA. In
these cases, use TEST.
Assembly/Compiler Coding Rule 40. (ML impact, M generality) Eliminate
unnecessary compare with zero instructions by using the appropriate conditional
jump instruction when the flags are already set by a preceding arithmetic
instruction. If necessary, use a TEST instruction instead of a compare. Be certain
that any code transformations made do not introduce problems with overflow.
Demnach sollte, wenn ich das alles richtig verstehe anstatt einer der beiden CMP bzw. AND Varianten besser auf TEST ausgewichen werden
Grüße
NicknameFJ
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller