在以下示例中,在64位体系结构上运行32位ELF的速度更快,但我不明白为什么。我尝试了两个示例,一个示例使用除法,另一个示例使用乘法。表现符合预期,但是该部门的表现令人惊讶。
我们在汇编程序上看到编译器正在调用的程序集,_alldiv
它在32位架构上模拟了64位除法,因此它必须比仅使用Assembly指令慢idiv
。所以我不明白我得到的结果:
我的设置是:Windows 10 x64,Visual Studio 2019
要计时我使用的代码Measure-Command { .\out.exe }
:
乘法
32位ELF:3360毫秒
64位ELF:1469毫秒
师
32位ELF:7383毫秒
64位ELF:8567毫秒
#include#include #include #include #include volatile int64_t m = 32; volatile int64_t n = 12; volatile int64_t result; int main(void) { for (size_t i = 0; i <(1 <<30); i++) { # ifdef DIVISION result = m / n; # else result = m * n; # endif m += 1; n += 3; } }
for (size_t i = 0; i <(1 <<30); i++) 00007FF60DA81000 mov r8d,40000000h 00007FF60DA81006 nop word ptr [rax+rax] { result = m / n; 00007FF60DA81010 mov rcx,qword ptr [n (07FF60DA83038h)] 00007FF60DA81017 mov rax,qword ptr [m (07FF60DA83040h)] 00007FF60DA8101E cqo 00007FF60DA81020 idiv rax,rcx 00007FF60DA81023 mov qword ptr [result (07FF60DA83648h)],rax m += 1; 00007FF60DA8102A mov rax,qword ptr [m (07FF60DA83040h)] 00007FF60DA81031 inc rax 00007FF60DA81034 mov qword ptr [m (07FF60DA83040h)],rax n += 3; 00007FF60DA8103B mov rax,qword ptr [n (07FF60DA83038h)] 00007FF60DA81042 add rax,3 00007FF60DA81046 mov qword ptr [n (07FF60DA83038h)],rax 00007FF60DA8104D sub r8,1 00007FF60DA81051 jne main+10h (07FF60DA81010h) } }
for (size_t i = 0; i <(1 <<30); i++) 00A41002 mov edi,40000000h 00A41007 nop word ptr [eax+eax] { result = m / n; 00A41010 mov edx,dword ptr [n (0A43018h)] 00A41016 mov eax,dword ptr ds:[00A4301Ch] 00A4101B mov esi,dword ptr [m (0A43020h)] 00A41021 mov ecx,dword ptr ds:[0A43024h] 00A41027 push eax 00A41028 push edx 00A41029 push ecx 00A4102A push esi 00A4102B call _alldiv (0A41CD0h) 00A41030 mov dword ptr [result (0A433A0h)],eax 00A41035 mov dword ptr ds:[0A433A4h],edx m += 1; 00A4103B mov eax,dword ptr [m (0A43020h)] 00A41040 mov ecx,dword ptr ds:[0A43024h] 00A41046 add eax,1 00A41049 mov dword ptr [m (0A43020h)],eax 00A4104E adc ecx,0 00A41051 mov dword ptr ds:[0A43024h],ecx n += 3; 00A41057 mov eax,dword ptr [n (0A43018h)] 00A4105C mov ecx,dword ptr ds:[0A4301Ch] 00A41062 add eax,3 00A41065 mov dword ptr [n (0A43018h)],eax 00A4106A adc ecx,0 00A4106D mov dword ptr ds:[0A4301Ch],ecx 00A41073 sub edi,1 00A41076 jne main+10h (0A41010h) } }
为了进一步调查Chris Dodd,我对代码进行了如下修改:
volatile int64_t m = 32000000000; volatile int64_t n = 12000000000; volatile int64_t result;
这次我有这些结果:
师
32位ELF:22407毫秒
64位ELF:17812毫秒
Chris Dodd.. 5
如果您查看x86处理器的指令时序,结果发现,在最新的Intel处理器上,64位除法的成本是32位除法的3-4倍-如果您查看alldiv的内部信息(上面的注释),对于始终适合32位的值,它将使用单个32位除法...
如果您查看x86处理器的指令时序,结果发现,在最新的Intel处理器上,64位除法的成本是32位除法的3-4倍-如果您查看alldiv的内部信息(上面的注释),对于始终适合32位的值,它将使用单个32位除法...