Warum C++-Code zur Überprüfung der Collatz-Vermutung schneller ist als handgeschriebenes Assembler
Ich lerne C++ und x86-Assembler und habe beschlossen, ein Programm zur Überprüfung der Collatz-Vermutung (3n+1) zu schreiben. Die Idee ist einfach: Nimm eine Zahl, wenn sie gerade ist — teile durch 2, wenn ungerade — multipliziere mit 3 und addiere 1. Es soll gezählt werden, wie viele Schritte nötig sind, um 1 zu erreichen.
Zuerst schrieb ich den Code in C++:
```cpp
int collatz(int n) {
int steps = 0;
while (n != 1) {
if (n % 2 == 0)
n /= 2;
else
n = 3 * n + 1;
steps++;
}
return steps;
}
```
Dann schrieb ich manuell eine Assembler-Version mit x86-64-Instruktionen, in der Annahme, dass sie schneller sein würde:
```asm
collatz_asm:
xor eax, eax ; steps = 0
.loop:
cmp edi, 1
je .done
test edi, 1
jnz .odd
shr edi, 1 ; gerade: n /= 2
inc eax
jmp .loop
.odd:
lea edi, [edi*2+edi+1] ; n = 3*n + 1
inc eax
jmp .loop
.done:
ret
```
Aber als ich die Leistung bei großen Zahlen gemessen habe (z.B. von 1 bis 10 M