测量执行简单指令的时间

时间:2012-03-10 21:02:31

标签: c++ profiling cycle

我正在尝试测量CPU执行特定指令所需的周期数(一个应占用一个CPU周期),输出必须是周期长度(CPU完成一个周期所需的时间)周期)。 首先,我的CPU是2.1GHz,这意味着我的计算机上的一个周期长度单位是1/2100,对吧? 另外 - 我使用getTimeOfDay来测量以微秒为单位的时间,并计算1,000,000次迭代的平均值。 因此,如果我没有弄错,我想要的输出必须是结果* 2100(为了得到循环长度)。我对吗? 谢谢!

P.S不知道这是否重要,但我正在用cpp写作

3 个答案:

答案 0 :(得分:3)

我相信你对一些事情有些误导。

在现代术语中,时钟速度是速度的指示,而不是速度的实际测量 - 因此没有合理的方法来估计单个指令可能需要多长时间。

你的问题是基于所有指令都相同的假设 - 它们肯定不是,某些CPU指令被解释为某些架构上的微指令序列,而其他指令可能会改变。

此外,您不能安全地假设在现代架构中重复指令将以相同的方式执行,这取决于数据和指令缓存,管道和分支预测。

getTimeOfDay的分辨率不足以估计测量单个指令所需的时间长度,甚至CPU时钟周期计数器(x86上的TSC)也不够。

此外,您的操作系统是估计此类时序的错误的主要来源,上下文切换,电源管理,机器负载和中断都会产生巨大影响。但即使在真正的硬实时操作系统(QNX或VxWorks)上,这样的测量仍然很困难,并且需要时间和工具以及解释结果的专业知识。在通用操作系统(Windows或基本Linux)上,您几乎没有希望获得准确的测量结果。

读取和存储CPU周期计数的计算开销和错误也会使一条指令所需的时间相形见绌。至少,我建议你考虑将数百或数千条指令组合在一起。

在没有高速缓存的确定性架构(1个周期= 1个指令)上,如PIC芯片,您可以使用时钟倍频器完全按照您的建议进行操作,但即使这样,您也可能需要使用逻辑分析仪验证测量结果(即你需要在硬件中这样做。)

简而言之,这是一个非常难的问题。

答案 1 :(得分:1)

CPU包含一个循环计数器,您可以通过一些内联汇编读取它:

static inline uint64_t get_cycles()
{
    uint64_t n;
    __asm__ __volatile__ ("rdtsc" : "=A"(n));
    return n;
}

如果你测量操作的1,2和300万次迭代的循环次数,你应该能够插入一次的成本,但一定要测量“空”循环以消除循环的成本:

{
    unsigned int n, m = get_cycles();
    for (unsigned int n = 0; n != 1000000; ++n)
    {
        // (compiler barrier)
    }
    n = get_cycles();

    // cost of loop: n - m
}

{
    unsigned int n, m = get_cycles();
    for (unsigned int n = 0; n != 1000000; ++n)
    {
        my_operation();
    }
    n = get_cycles();

    // cost of 1000000 operations: n - m - cost of loop
}

// repeat for 2000000, 3000000.

答案 2 :(得分:1)

  

我正在尝试衡量计算机执行简单指令所需的时间

如果是这种情况,那么钥匙甚至不是您能找到的最准确的时间功能。我敢打赌,没有必要提供必要的决议来提供有意义的结果。

关键是增加样品数量。

所以不要做类似的事情:

start = tik();
instruction();
end = tok();
time = end - start;

DO

start = tik();
for ( 1..10000 )
   instruction();
end = tok();
time = (end - start) / 10000;

这将提供更准确的结果,并且由测量机制引起的误差将是可忽略的。