【问题标题】:Measuring time to perform simple instruction测量执行简单指令的时间
【发布时间】:2012-03-10 21:02:31
【问题描述】:

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

P.S 不知道是否重要,但我是用 cpp 写的

【问题讨论】:

  • 您认为getTimeOfDay() 需要多少个时钟周期?另外,您为什么想知道这些信息?您可能可以在英特尔网站(或您分析的芯片制造商生产的任何制造商)的某处查找每条指令所需的周期数。您自己尝试这样做是不可能的。
  • 我认为唯一有意义的性能衡量标准是执行操作的时间(而不是周期)。所花费的时间和周期都取决于 CPU/机器架构以及您自己的程序(例如,它在内存中做了多少“长”跳转)。然而,时间是大多数人会注意到的。
  • @KerrekSB,让它成为一个答案。简单但正确。
  • 我改写了我的问题,希望现在更有意义
  • Callgrind + Kcachegrind 可以帮助您分析您的应用程序。

标签: c++ profiling cycle


【解决方案1】:

我相信您在一些事情上被误导了。

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

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

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

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

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

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

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

简而言之,这是一个极其困难的问题。

【讨论】:

    【解决方案2】:

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

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

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

    {
        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.
    

    【讨论】:

      【解决方案3】:

      我正在尝试测量我的计算机执行一个简单指令所花费的时间

      如果是这样,关键甚至不是您能找到的最准确的时间函数。我敢打赌,没有人有必要的分辨率来提供有意义的结果。

      关键是增加样本数。

      所以不要做类似的事情:

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

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

      这将提供更准确的结果,测量机构造成的误差可以忽略不计。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-11
        • 2015-06-28
        • 1970-01-01
        • 2015-12-10
        • 1970-01-01
        • 2021-07-03
        相关资源
        最近更新 更多