zondag 18 maart 2018

Assembler is sneller dan C++

Gisteren een video gezien van een Assembler expert die uitdrukkelijk beweert dat het een leugen is dat C++ tegenwoordig sneller is dan Assembler.

Laten we een test doen. Bijvoorbeeld een array vullen met 0.

Om maximaal nut te hebben van de 64bits architectuur doe ik het volgende in C++:

Uint64* pixels64bit = (Uint64 *)pixels;
for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }

Bovenstaande loop duurt 1.05ms.

Nu in Assembler:
ClearArray proc
    push rdi
    xchg rcx, rdx
    mov rdi, rdx
    xor rax, rax
    rep stosq
    pop rdi
    ret
ClearArray endp

En dat duurt 0.15ms.

Hoe komt het dat de Assembler versie 8 keer sneller is? Als we naar de gegenereerde code van C++ kijken, dan zien we het:

CPP:   Uint64* pixels64bit = (Uint64 *)pixels;
00007FF7F1CE1A9A  mov         rax,qword ptr [pixels]  
00007FF7F1CE1AA1  mov         qword ptr [rbp+218h],rax  
CPP:   for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
00007FF7F1CE1AA8  mov         dword ptr [rbp+234h],0  
00007FF7F1CE1AB2  jmp         wWinMain+1E2h (07FF7F1CE1AC2h)  
00007FF7F1CE1AB4  mov         eax,dword ptr [rbp+234h]  
00007FF7F1CE1ABA  inc         eax  
00007FF7F1CE1ABC  mov         dword ptr [rbp+234h],eax  
00007FF7F1CE1AC2  cmp         dword ptr [rbp+234h],80100h  
00007FF7F1CE1ACC  jge         wWinMain+206h (07FF7F1CE1AE6h)  
00007FF7F1CE1ACE  movsxd      rax,dword ptr [rbp+234h]  
00007FF7F1CE1AD5  mov         rcx,qword ptr [rbp+218h]  
00007FF7F1CE1ADC  mov         qword ptr [rcx+rax*8],0  
00007FF7F1CE1AE4  jmp         wWinMain+1D4h (07FF7F1CE1AB4h)  

Dit kan dus nooit sneller zijn, dan de rep stosq.
Trouwens, een C++ functie zoals:
std::fill(pixels64bit, pixels64bit + (DIMx*DIMy/2), 0);
duurt ook ruim 1.00ms.

Geen opmerkingen:

Een reactie posten