CPU指令与持续时间

时间:2016-08-02 07:51:16

标签: c++ duration instructions

我有两个不同的程序来解决用C ++编写的数学问题(程序AB)。

A执行的轮次比B好10倍(就持续时间而言)。现在我通过valgrind工具callgrind计算了执行的CPU指令,并意识到程序A只需要程序B执行的指令的1/3。我原以为这个因素是1/10左右。

我知道CPU指令需要更多的CPU周期(比如内存访问),但是设计A应该包含比B更多的昂贵指令。 另外我不知道callgrind如何计算这些指令(在文档中找不到任何相关内容)。
任何人都可以对这种行为给出合理的解释吗? TIA

编辑:(由于评论)
不幸的是,代码是全面的在这里发布...两个程序都在同一台机器上执行。两者都是完全并行化的(每个线程运行一个程序的独立副本,只需要在找到解决方案时告诉其他线程)。但指令计数是在一个线程上完成的,因为callgrind无论如何都会对程序进行排序。如上所述,A需要的内存远远超过B
我不希望得到一个正确的答案,只是给我一些提示,可能会导致这个问题很好。

1 个答案:

答案 0 :(得分:1)

您也没有指定运行该平台的平台,每个CPU都有自己的一套“不做/不做”。

例如,在x86上,指令数与总执行时间之间的相关性非常小,如下:

  1. x86首先将指令转换为内部微操作码(uops)并运行那些指令,因此它基本上执行的代码与可执行文件中人类可见的机器代码完全不同。它也重新排序uop,所以即使你模拟翻译,你也不能确定它们的执行顺序(除非你模拟CPU,缓存和内存的整个架构)。
  2. 多个微指令可以在单个时钟周期内执行,或者其他方式,单个uop可能会阻塞CPU几个时钟周期,因此任何两个x86指令的执行时间可能相差100倍以上(即使是相同的指令也是如此)如果在高速缓存未命中时停止,则两次运行可能会有很大的不同(~100x)执行时间。
  3. 内存访问。内存比CPU慢得多,因此以可预测的模式顺序读取内存并使数据尽可能紧凑(完全重用缓存)与代码速度比指令数(算法)更相关。在某些极端情况下,设计良好的数据结构可以击败更好的算法,例如std::vector<int>对于~100k项目随机插入/删除比列表快得多,尽管向量inser / remove是O(n ^ 2) ),而list只是O(n)。 CPU手的唯一内存是L0缓存,L1就像在街上,L2就像是去其他城市,L3不同的国家。记忆本身就像月亮一样。
  4. 其他I / O访问..如果内存很慢,那么访问光盘就像去太阳(SSD)或太阳系(HDD)之外。
  5. 正如您所看到的,在极端情况下,x86 CPU甚至可以执行具有~200条指令的代码+处理30倍以上的内存,与具有~10条指令的不同例程一样快。在角落的情况下,差异可能非常极端,人类很难通过阅读来源来想象。这就是为什么在x86上验证代码优化的唯一有效方法是使用足够接近实际数据的数据来分析代码。 &#34;优化&#34;只是通过理论,大写符号和&#34;直觉和#34;可以很容易地适得其反,10-20y有效,即便如此,我们用工具来分析结果,以验证收益。

    当然,更大量的指令本身可以更容易从缓存中脱落,使得指令读取停止,但如果你可以创建更好的数据结构,那么甚至30kiB对1kiB的代码也是合理的(尽管它有很多风险)在被OS中断时缓存未命中。)

    callgrind网站说:&#34;可选地,缓存模拟和/或分支预测(类似于Cachegrind)可以产生关于应用程序的运行时行为的进一步信息。&#34; ,所以你可以得到比指令数更精细的数据,看看是否存在一些瓶颈,重组代码/数据会使它停滞不前。

相关问题