这并不简单。在Intel® 64和IA-32体系结构开发人员手册:第3B卷中描述了这样一件事:以下是其行为:对于Pentium M处理器,对于Pentium 4处理器、英特尔Xeon处理器和P6系列处理器:时间戳计数器会随着每个内部处理器时钟周期递增。内部处理器时钟周期由当前的核心时钟与总线时钟比率确定。Intel® SpeedStep®技术的转换也可能影响处理器时钟。对于Pentium 4处理器,英特尔Xeon处理器;对于英特尔Core Solo和英特尔Core Duo处理器;对于英特尔Xeon处理器5100系列和英特尔Core 2 Duo处理器;对于英特尔Core 2和英特尔Xeon处理器;对于英特尔Atom处理器:时间戳计数器以恒定速率递增。该速率可以由处理器的最大核心时钟与总线时钟比率设置,也可以由处理器启动时设置的最大解析频率设置。最大已解析频率可能与处理器基础频率不同。在某些处理器上,TSC频率可能与品牌字符串中的频率不同。这是您用例的建议:为了确定平均处理器时钟频率,英特尔建议使用性能监视逻辑来计算所需平均值的一段时间内处理器核心时钟的计数。有关更多信息,请参见第18.17节“在基于Intel NetBurst®微架构的处理器上具有Intel Hyper-Threading Technology的系统中计数时钟”和第19章“性能监视事件”。坏消息是,据我所知,性能计数器通常无法在AMD和英特尔处理器之间移植。因此,您必须确保检查使用AMD文档中的哪些性能计数器。还存在一些复杂性:您不能轻松地测量任意代码所需的周期数。例如,处理器可能会暂停或进入睡眠模式(请参见C状态)或操作系统可以执行一些无法在没有高权限的情况下进行配置文件记录的受保护代码(出于安全考虑)。只要您需要测量相对较长时间(至少几十个周期)的数值密集型代码的周期数,此方法就很好。最重要的是,MSR的文档和使用非常复杂,并且有一些限制。像CPU_CLK_UNHALTED.THREAD和CPU_CLK_UNHALTED.REF_TSC这样的性能计数器似乎是衡量您想要衡量的内容的好起点。使用库来读取这些性能计数器通常是一个非常好的想法(除非您喜欢头痛至少几天)。PAPI可能足以完成此工作。以下是一些有趣的相关帖子: 英特尔上的丢失周期?rdtsc和CPU_CLK_UNHALTED.REF_TSC之间的不一致性 如何通过rdpmc指令读取性能计数器?
perf stat --all-user ./my_program
会默认计算cycles
硬件PMU事件以及instructions
和其他一些事件。--all-user
使它将PMU编程为仅在CPU处于非内核特权级别时进行计数。这很容易,除非您想要进入微小的测量间隔,在此情况下,使用rdpmc
在程序中计时(在调用系统调用以对PMU进行编程后),此时测量开销和乱序执行成为一个巨大的问题。 - Peter Cordesperf stat -p <PID>
,它会附加到您的程序上(示例)。或者使用更现代的perf
,通过编写管道来启用/禁用 perf 事件收集,让被分析的程序控制perf stat
。 - Peter Cordes