Als erstes habe ich eine Referenz-Klasse geschrieben, in der ich alle Operationen in C++ umgesetzt habe. Damit wollte ich überprüfen ob mein Assembler Code schneller ist .. :D
Nun beim schreiben der eigentlichen Klasse mit den Operationen in inline assembler bin ich auf ein Problem gestossen, mit dem ich nichts anfangen kann.
Ich messe die Zeit, die die einzelnen Operatoren brauchen um 10.000.000 iterationen durchzuführen. (10 mio additions, bit-shifts etc.)
Der Code dazu sieht so aus:
Code: Alles auswählen
#define ITERATIONS 10000000
DWORD start, end;
LargeAsmInt asm1, asm2;
asm1 = "0x53ab9803ac56c76fd43ac45364bc898b76fd43ac";
asm2 = "0x0a5bc76fd43ac564bc87efd5453ab980998bcdea";
LargeInt<128> int1, int2;
int1 = "0x53ab9803ac56c76fd43ac45364bc898b76fd43ac";
int2 = "0x0a5bc76fd43ac564bc87efd5453ab980998bcdea";
start = GetTickCount();
for (long i = 0; i < ITERATIONS; ++i)
asm1 + asm2;
end = GetTickCount();
printf("Addition LargeAsmInt: %d\n", end - start);
start = GetTickCount();
for (long i = 0; i < ITERATIONS; ++i)
int1 + int2;
end = GetTickCount();
printf("Addition LargeInt: %d\n", end - start);
Nun zu meinem Problem: Wenn ich jetzt den Operator += hinzunehme verlangsamt sich die Ausführungszeit der anderen Operatoren um ca 2 Sekunden. Ich habe keine Ahnung woran das liegt und versucht das Problem ausfindig zu machen indem ich im += Operator alles auskommentiert habe und dann Zeile für Zeile wieder eingefügt habe.
Das Problem tritt erst auf wenn ich ein Jump im inline assembler zu einem Label mache. (Laut meinen Messungen macht es keinen unterschied ob ich jnz oder jmp benutze. Hier der Code von meinem += Operator:
Code: Alles auswählen
LargeAsmInt& LargeAsmInt::operator+= (LargeAsmInt& inOther)
{
uint32_t *thisData = this->data,
*otherData = inOther.data;
__asm
{
mov ecx, 0 // loop counter
mov edi, thisData // this pointer
mov esi, otherData // inOther reference
mov ebx, _LARGEASMINT_LENGTH_
mov eax, [esi+ecx*4]
add [edi+ecx*4], eax
inc ecx
dec ebx
jz after_loop
/*before_loop:
mov eax, [esi+ecx*4]
adc [edi+ecx*4], eax
inc ecx
dec ebx
jnz before_loop*/
after_loop:
}
Code: Alles auswählen
Addition LargeAsmInt: 2890
Addition LargeInt: 4282
+= LargeInt: 6203
Shift << LargeAsmInt: 2906
Shift << LargeInt: 5812
Code: Alles auswählen
Addition LargeAsmInt: 4875
Addition LargeInt: 6078
+= LargeAsmInt: 3843
+= LargeInt: 7938
Shift << LargeAsmInt: 4734
Shift << LargeInt: 5782
Weiss zufällig jemand woran das liegen kann? Ich habe versucht bei MSDN und in Google was dazu zu finden - leider erfolglos. Da ich erst vor kurzem in Assembler eingestiegen bin fehlt mir noch die Erfahrung/das Wissen.
Btw. Ich arbeite mit Visual C++ 2008 Express Edition.