通过计算装配说明来测量CPU速度

时间:2011-08-10 03:37:37

标签: c visual-c++ assembly x86 cpu-speed

编辑:我原来的例子有一个愚蠢的错误。在修好之后,我仍然会得到奇怪的结果。


在我天真的尝试以“蛮力”的方式衡量我的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);
}

将其分解为:

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

请注意,循环是3条指令,因此eax的最终值应该是指令总数。

为什么我在运行时会得到4.2?

4 个答案:

答案 0 :(得分:11)

因为instruction-level parallelismsuperscalar architecture允许在单个pipelined时钟周期内执行多条指令。

例如,在您的代码中,branch prediction 通过以下方式有效消除<{strong> cmp指令,除了最后一次_loop次迭代:

  1. 并行执行cmpjb
  2. 始终选择jb分支。
  3. 当然,(2)在 last 迭代中抛出,导致管道被清除。额外的~20个周期(对于20级流水线)可忽略不计,因为您的循环大约为10 ^ 9条指令。

      

    编译器不应该优化这个

    处理器硬件始终在数据路径中寻找优化机会;编译器只是尝试组织指令来利用给定体系结构的模式。例如,硬件流水线操作可以在没有software pipelining的情况下增加IPC,特别是对于相对hazard的免费代码,例如您的示例。

答案 1 :(得分:9)

由于CPU速度不是以每秒字节数来衡量,而是以每秒的指令周期来衡量,特别是在x86上,因此某些指令需要超过1个周期。

请参阅this page了解指令时间。 (实际上,这只能达到486 - 仍在寻找现代处理器的良好参考。)

答案 2 :(得分:2)

指令执行的周期数与字节的大小没有直接关系。除了具有多个执行单元和推测执行的现代CPU功能之外,还不可能事先确定给定的代码块需要多长时间才能执行的准确性。

答案 3 :(得分:1)

您可以使用 rdtsc 指令测量循环,该指令计算CPU内部频率的周期。两个读数之间的差异是经过的循环次数。让你的代码执行1000个循环,乘以3(循环中的指令)并除以经过的循环。这将为您提供每个周期的说明。然后,您可以根据CPU自己的频率进行扩展。

请记住,由于您的代码太短,很可能会从缓存级别1(或预取器内部)执行,这使得它仅对该情况有效,而不是一般的CPU。流水线可能太短,无法做出有价值的东西。

至于教学时间this page似乎比AShelly建议的更新。它由Torbjörn GranlundSwedish Royal Institute of Technology定期重新计算。