一个函数在应用程序中花费的总时间可以大致分为两个部分:
- 实际计算所花费的时间 (Tcomp)
- 内存访问所花费的时间 (Tmem)
通常,分析器提供函数花费的总时间的估计。是否可以根据上述两个组件(Tcomp 和 Tmem)估算所花费的时间?
一个函数在应用程序中花费的总时间可以大致分为两个部分:
通常,分析器提供函数花费的总时间的估计。是否可以根据上述两个组件(Tcomp 和 Tmem)估算所花费的时间?
Roofline 模型提出了算术强度的概念: https ://crd.lbl.gov/departments/computer-science/PAR/research/roofline/ 。简单地说,它定义了为每次内存访问执行的算术指令的数量。
计算算术强度通常是通过使用性能计数器来实现的。
Brendan Gregg 在他最近的博客文章CPU Utilization is Wrong中建议使用每周期 PMC 指令。简而言之,如果 IPC < 1.0,则可以认为应用程序受内存限制。否则它可以被认为是指令绑定。以下是他帖子的相关摘录:
如果您的 IPC < 1.0,您可能会出现内存停滞,软件调优策略包括减少内存 I/O、改善 CPU 缓存和内存局部性,尤其是在 NUMA 系统上。硬件调优包括使用具有更大 CPU 缓存和更快内存、总线和互连的处理器。
如果您的 IPC > 1.0,您可能会受到指令限制。寻找减少代码执行的方法:消除不必要的工作、缓存操作等。CPU 火焰图是这项调查的好工具。对于硬件调优,尝试更快的时钟频率和更多的内核/超线程。
对于我的上述规则,我在 1.0 的 IPC 上进行拆分。我从哪里得到的?根据我之前在 PMC 的工作,我弥补了这一点。以下是如何获得为您的系统和运行时自定义的值:编写两个虚拟工作负载,一个受 CPU 限制,一个受内存限制。测量他们的 IPC,然后计算他们的中点。
以下是压力工具及其 IPC生成的虚拟工作负载的一些示例。
内存限制测试,IPC 低 (0,02):
$ perf stat stress --vm 4 -t 3
stress: info: [4520] dispatching hogs: 0 cpu, 0 io, 4 vm, 0 hdd
stress: info: [4520] successful run completed in 3s
Performance counter stats for 'stress --vm 4 -t 3':
10767,074968 task-clock:u (msec) # 3,560 CPUs utilized
0 context-switches:u # 0,000 K/sec
0 cpu-migrations:u # 0,000 K/sec
4 555 919 page-faults:u # 0,423 M/sec
4 290 929 426 cycles:u # 0,399 GHz
67 779 143 instructions:u # 0,02 insn per cycle
18 074 114 branches:u # 1,679 M/sec
5 398 branch-misses:u # 0,03% of all branches
3,024851934 seconds time elapsed
CPU绑定测试,IPC高(1,44):
$ perf stat stress --cpu 4 -t 3
stress: info: [4465] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
stress: info: [4465] successful run completed in 3s
Performance counter stats for 'stress --cpu 4 -t 3':
11419,683671 task-clock:u (msec) # 3,805 CPUs utilized
0 context-switches:u # 0,000 K/sec
0 cpu-migrations:u # 0,000 K/sec
108 page-faults:u # 0,009 K/sec
30 562 187 954 cycles:u # 2,676 GHz
43 995 290 836 instructions:u # 1,44 insn per cycle
13 043 425 872 branches:u # 1142,188 M/sec
26 312 747 branch-misses:u # 0,20% of all branches
3,001218526 seconds time elapsed
这是不可能测量的(这样做没有任何意义),因为计算与当前处理器架构中的内存访问重叠。此外,访问内存通常被分解为更多步骤(访问内存、预取到各种缓存级别、实际读取处理器寄存器)。
您可以使用 perf 及其硬件计数器(如果您的硬件支持)来测量各种缓存级别的缓存命中和未命中,以估计您的算法在硬件上的效率。
如果您正在寻找获取 CPU 周期的函数,那么 boost 将非常有帮助。我使用 Boost Timer Utility 来计算系统调用的 CPU 周期。
另一方面,您可以将相同的功能放在完整的程序上以获得整体时间。
我希望这就是你要找的。-维杰