Meh*_*dad 10 c x86 assembly cpu-speed visual-c++
编辑:我原来的例子有一个愚蠢的错误.修好之后,我仍然会得到奇怪的结果.
在我天真的尝试以"蛮力"的方式测量我的CPU速度时,我制作了以下程序:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma comment(linker, "/entry:mainCRTStartup")
#pragma comment(linker, "/Subsystem:Console")
int mainCRTStartup()
{
char buf[20];
clock_t start, elapsed;
unsigned long count = 0;
start = clock();
__asm
{
mov EAX, 0;
_loop:
add EAX, 3; // accounts for itself and next 2 instructions
cmp EAX, 0xFFFFFFFF - 0x400;
jb _loop;
mov count, EAX;
}
elapsed = clock() - start;
_gcvt(count * (long long)CLOCKS_PER_SEC / (elapsed * 1000000000.0), 3, buf);
puts(buf);
}
Run Code Online (Sandbox Code Playgroud)
哪个反汇编成:
mainCRTStartup:
push ebp
mov ebp,esp
sub esp,28h
mov dword ptr [count],0
call dword ptr [_clock]
mov dword ptr [start],eax
mov eax,0
_loop:
add eax,03h
cmp eax,0FFFFFBFFh
jb _loop
mov dword ptr [count],eax
call dword ptr [_clock]
sub eax,dword ptr [start]
... // call _gcvt, _puts, etc.
mov esp,ebp
pop ebp
ret
Run Code Online (Sandbox Code Playgroud)
请注意,循环是3条指令,因此最终值eax应该是指令的总数.
我运行时为什么会得到4.2?
Jus*_*yes 12
因为指令级并行和超标量体系结构允许多个指令在单个流水线时钟周期中执行.
例如,在您的代码中,分支预测 有效地消除了cmp除最后_loop一次迭代之外的所有指令,方法是:
cmp与jb在平行的,并且jb分公司.当然,(2)在最后一次迭代时被抛出,这导致管道被清除.额外的~20个周期(对于20级流水线)可以忽略不计,因为您的循环大约为10 ^ 9指令.
编译器不应该优化它
处理器硬件始终在数据路径中寻找优化机会; 编译器只是尝试组织指令来利用给定体系结构的模式.例如,硬件流水线可以在没有软件流水线的情况下增加IPC ,特别是对于相对无危险的代码,例如您的示例.