Nazdar,
moh by mi někdo vysvětlit proč proboha není rychlejší specializovaná instrukce X86 procesoru (movs) na přesunutí řetězce bajtů než její opis pomocí cyklu a prostého přesunutí jednotlivých prvků pomocí instrukce mov? Opravdu to nechápu ... Když je to specializovaná instrukce, tak snad by měla bejt rychlejší ne ... Asi ne. Dole zmiňuji kód na kterém jsem měřil rychlost.
#include <iostream>
int main()
{
using namespace std;
int one[5] = {10,20,30,40,50};
int two[5] = {0};
for (register int i=0;i<1000000000;++i)
{
/*for (register int i=0;i<5;++i)
{
two[i] = one[i];
}*/
asm(
".intel_syntax noprefix;"
"mov rsi , %0;"
"mov rdi , %1;"
"mov rcx , 5;"
"rep movsd;"
".att_syntax noprefix;"
:
: "r"(one), "r"(two)
: "rcx","rsi","rdi"
);
}
for (int i=0;i<5;++i)
cout << one[i] << " ,";
cout << endl;
for (int i=0;i<5;++i)
cout << two[i] << " ,";
return 0;
}
// ASM -> 8,722 s
// Cyklus ->10,399 s
// Cyklus s register counterem --> 5,022 s !!! WHY !!!
Zde je kód v ASM funkce main s cyklem :
0x4009c0 push rbp
0x4009c1 mov rbp,rsp
0x4009c4 push r12
0x4009c6 push rbx
0x4009c7 sub rsp,0x40
0x4009cb mov DWORD PTR [rbp-0x30],0xa
0x4009d2 mov DWORD PTR [rbp-0x2c],0x14
0x4009d9 mov DWORD PTR [rbp-0x28],0x1e
0x4009e0 mov DWORD PTR [rbp-0x24],0x28
0x4009e7 mov DWORD PTR [rbp-0x20],0x32
0x4009ee mov QWORD PTR [rbp-0x50],0x0
0x4009f6 mov QWORD PTR [rbp-0x48],0x0
0x4009fe mov DWORD PTR [rbp-0x40],0x0
0x400a05 mov r12d,0x0
0x400a0b jmp 0x400a2e <main()+110>
0x400a0d mov ebx,0x0
0x400a12 jmp 0x400a25 <main()+101>
0x400a14 movsxd rax,ebx
0x400a17 mov edx,DWORD PTR [rbp+rax*4-0x30]
0x400a1b movsxd rax,ebx
0x400a1e mov DWORD PTR [rbp+rax*4-0x50],edx
0x400a22 add ebx,0x1
0x400a25 cmp ebx,0x4
0x400a28 jle 0x400a14 <main()+84>
0x400a2a add r12d,0x1
0x400a2e cmp r12d,0x3b9ac9ff
0x400a35 jle 0x400a0d <main()+77>
0x400a37 mov DWORD PTR [rbp-0x14],0x0
0x400a3e jmp 0x400a66 <main()+166>
0x400a40 mov eax,DWORD PTR [rbp-0x14]
0x400a43 cdqe
0x400a45 mov eax,DWORD PTR [rbp+rax*4-0x30]
0x400a49 mov esi,eax
0x400a4b mov edi,0x601080
0x400a50 call 0x400820 <_ZNSolsEi@plt>
0x400a55 mov esi,0x400bb1
0x400a5a mov rdi,rax
0x400a5d call 0x400880 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x400a62 add DWORD PTR [rbp-0x14],0x1
0x400a66 cmp DWORD PTR [rbp-0x14],0x4
0x400a6a jle 0x400a40 <main()+128>
0x400a6c mov esi,0x4008a0
0x400a71 mov edi,0x601080
0x400a76 call 0x400890 <_ZNSolsEPFRSoS_E@plt>
0x400a7b mov DWORD PTR [rbp-0x18],0x0
0x400a82 jmp 0x400aaa <main()+234>
0x400a84 mov eax,DWORD PTR [rbp-0x18]
0x400a87 cdqe
0x400a89 mov eax,DWORD PTR [rbp+rax*4-0x50]
0x400a8d mov esi,eax
0x400a8f mov edi,0x601080
0x400a94 call 0x400820 <_ZNSolsEi@plt>
0x400a99 mov esi,0x400bb1
0x400a9e mov rdi,rax
0x400aa1 call 0x400880 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x400aa6 add DWORD PTR [rbp-0x18],0x1
0x400aaa cmp DWORD PTR [rbp-0x18],0x4
0x400aae jle 0x400a84 <main()+196>
0x400ab0 mov eax,0x0
0x400ab5 jmp 0x400abf <main()+255>
0x400ab7 mov rdi,rax
0x400aba call 0x4008c0 <_Unwind_Resume@plt>
0x400abf add rsp,0x40
0x400ac3 pop rbx
0x400ac4 pop r12
0x400ac6 pop rbp
0x400ac7 ret
Zde je ASM kód funkce main s mnou vložením řešením pomocí specializované instrukce :
0x4009c0 push rbp
0x4009c1 mov rbp,rsp
0x4009c4 push rbx
0x4009c5 sub rsp,0x48
0x4009c9 mov DWORD PTR [rbp-0x30],0xa
0x4009d0 mov DWORD PTR [rbp-0x2c],0x14
0x4009d7 mov DWORD PTR [rbp-0x28],0x1e
0x4009de mov DWORD PTR [rbp-0x24],0x28
0x4009e5 mov DWORD PTR [rbp-0x20],0x32
0x4009ec mov QWORD PTR [rbp-0x50],0x0
0x4009f4 mov QWORD PTR [rbp-0x48],0x0
0x4009fc mov DWORD PTR [rbp-0x40],0x0
0x400a03 mov ebx,0x0
0x400a08 jmp 0x400a24 <main()+100>
0x400a0a lea rax,[rbp-0x30]
0x400a0e lea rdx,[rbp-0x50]
0x400a12 mov rsi,rax
0x400a15 mov rdi,rdx
0x400a18 mov rcx,0x5
0x400a1f rep movs DWORD PTR es:[rdi],DWORD PTR ds:[rsi]
0x400a21 add ebx,0x1
0x400a24 cmp ebx,0x3b9ac9ff
0x400a2a jle 0x400a0a <main()+74>
0x400a2c mov DWORD PTR [rbp-0x14],0x0
0x400a33 jmp 0x400a5b <main()+155>
0x400a35 mov eax,DWORD PTR [rbp-0x14]
0x400a38 cdqe
0x400a3a mov eax,DWORD PTR [rbp+rax*4-0x30]
0x400a3e mov esi,eax
0x400a40 mov edi,0x601080
0x400a45 call 0x400820 <_ZNSolsEi@plt>
0x400a4a mov esi,0x400ba1
0x400a4f mov rdi,rax
0x400a52 call 0x400880 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x400a57 add DWORD PTR [rbp-0x14],0x1
0x400a5b cmp DWORD PTR [rbp-0x14],0x4
0x400a5f jle 0x400a35 <main()+117>
0x400a61 mov esi,0x4008a0
0x400a66 mov edi,0x601080
0x400a6b call 0x400890 <_ZNSolsEPFRSoS_E@plt>
0x400a70 mov DWORD PTR [rbp-0x18],0x0
0x400a77 jmp 0x400a9f <main()+223>
0x400a79 mov eax,DWORD PTR [rbp-0x18]
0x400a7c cdqe
0x400a7e mov eax,DWORD PTR [rbp+rax*4-0x50]
0x400a82 mov esi,eax
0x400a84 mov edi,0x601080
0x400a89 call 0x400820 <_ZNSolsEi@plt>
0x400a8e mov esi,0x400ba1
0x400a93 mov rdi,rax
0x400a96 call 0x400880 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x400a9b add DWORD PTR [rbp-0x18],0x1
0x400a9f cmp DWORD PTR [rbp-0x18],0x4
0x400aa3 jle 0x400a79 <main()+185>
0x400aa5 mov eax,0x0
0x400aaa jmp 0x400ab4 <main()+244>
0x400aac mov rdi,rax
0x400aaf call 0x4008c0 <_Unwind_Resume@plt>
0x400ab4 add rsp,0x48
0x400ab8 pop rbx
0x400ab9 pop rbp
0x400aba ret
Měření efektivity bylo prováděno bez závěrečného vypsání obou polí.