当前位置: 首页 > 知识库问答 >
问题:

估计每个指令的周期

魏书
2023-03-14

我已经反汇编了一个用MSVC v140编译的小型C程序,并试图估计每条指令的周期,以便更好地理解代码设计如何影响性能。我一直在关注迈克·阿克顿(MikeActon)关于“面向数据的设计和C”的CppCon 2014演讲,特别是我链接到的部分。

他在信中指出了以下几行:

movss   8(%rbx), %xmm1
movss   12(%rbx), %xmm0

然后他声称,这些2 x 32位读取可能位于同一缓存线上,因此大约需要200个周期。

《英特尔64和IA-32体系结构优化参考手册》是一本很好的资源,特别是“附录C-指令延迟和吞吐量”。然而,在“表C-16.数据流单指令多数据扩展单精度浮点指令”的C-15页上,它指出MOVS仅为1个周期(除非我理解延迟在这里的含义是错误的……如果是,我该如何理解这一点?)

我知道,对执行时间的理论预测永远不会正确,但这一点值得学习。这两个命令是如何循环200个周期的,我如何才能学会推理这个代码段之外的执行时间?

我已经开始阅读一些关于CPU管道的内容。。。也许大部分的周期都在那里被发现了?

PS:我对实际测量硬件性能计数器不感兴趣。我只是想学习如何合理地看ASM和周期。

共有1个答案

宿镜
2023-03-14

正如您已经指出的,MOVSS指令的理论吞吐量和延迟为1个周期。您正在查看正确的文档(英特尔优化手册)。Agner Fog(在评论中提到)在他的Intruction Tables for Intel CPU中测量了相同的数字(AMD具有更高的延迟)。

这就引出了第一个问题:你在研究什么样的微体系结构?即使对于同一家供应商来说,这也会带来很大的不同。Agner Fog报告称,根据源和目标(寄存器vs内存),AMD推土机上的MOVS延迟为2-6cy。在研究计算机体系结构的html" target="_blank">性能时,必须牢记这一点。

正如dwelch在评论中指出的那样,200cy很可能是缓存未命中。从优化手册中获得的任何内存访问指令的数字都是在假设数据驻留在一级缓存(L1)中的情况下得出的。现在,如果以前的指令从未接触过数据,则需要将缓存线(Intel和AMD x86的64字节)从内存加载到最后一级缓存,从那里加载到第二级缓存,然后加载到L1,最后加载到XMM寄存器(在1个周期内)。L3-L2和L2-L1之间的传输具有吞吐量(而不是延迟!)当前英特尔微体系结构上每个缓存线的两个周期。内存带宽可用于估计L3和内存之间的吞吐量(例如,具有40 GB/s可实现内存带宽的2 GHz CPU将具有每个缓存线3.2个周期的吞吐量)。缓存线或内存块通常是可以操作的最小单元缓存和内存,它们在微体系结构之间有所不同,甚至在体系结构内也可能有所不同,具体取决于缓存级别(L1、L2等)。

现在这都是吞吐量,而不是延迟,这不会帮助您估计您上面描述的内容。为了验证这一点,您需要一遍又一遍地执行指令(至少1/10秒)以获得周期准确的测量值。通过更改指令,您可以决定是要测量延迟(通过包括指令之间的依赖关系)还是吞吐量(通过让指令输入独立于先前指令的结果)。要测量缓存和内存访问,您需要预测访问是否会访问缓存,这可以使用层条件来完成。

估计英特尔CPU指令执行(延迟和吞吐量)的工具是英特尔架构代码分析器,它支持多种微架构,最高可达Haswell。延迟预测是半信半疑的,因为估计延迟比估计吞吐量要困难得多。

 类似资料:
  • 假设我有几个指令:“戏剧”、“喜剧”,出于某种原因,它们有很多不同的属性,所以有一个“电影”指令并不一定有意义。有没有一种方法可以根据范围变量动态评估指令?大致如下: 它的评估结果如下: 我是Angular的新手,所以请原谅疯狂的想法。 更新:实际上我刚刚发现了一篇关于完全相同的问题/解决方案的文章:http://onehungrymind.com/angularjs-dynamic-templa

  • 我知道无符号long-long存储在eax/edx中,但我想知道如何找出执行单个rdtsc指令所需的时钟周期? 编辑:像这样的东西有用吗? .GlobalRDTSC rdtsc: rdtsc rdtsc ret

  • 我有一个名为-'users'的示例sql表,其中包含以下记录: 我想获得每一个用户的计数在每日,每周和每月的基础上与预期的outlike为:

  • 我想在我的应用程序中显示三个月,但我不知道如何显示,请帮助我如何做,这是我的代码为星期显示。谢谢你 @override protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(r.layout.main_display);

  • 我需要以下场景: 在一个周期内运行所有,并在所有任务完成执行后每次调用方法时调用。在实际调度周期之后调用时,下一个调度周期不得等待。 简而言之:在实际调度周期完成后调用方法,并且不停止下一个调度周期 下面的代码创建任务和调度工作。但是,当一个周期内的所有任务都完成时,我无法调用tasksCompleted()。

  • 问题内容: 我有一个创建输入字段的指令。我需要将此输入字段的ng-model属性设置为$ rootScope变量的值。这背后的原因是我希望输入字段位于布局中,并根据加载的页面绑定到不同的模型。我以为我会在每个控制器中设置此全局变量,然后在指令中对其进行访问。 ATM变量是硬编码的 和指令 它被渲染为 输入字段中的文本是mymodel变量的值。console.log显示 任何人都可以在这个问题上阐明