繁体   English   中英

如何描述在C / C ++应用程序中花在内存访问上的时间?

[英]How to profile time spent in memory access in C/C++ applications?

函数在应用程序中花费的总时间可以大致分为两个部分:

  1. 花在实际计算上的时间(Tcomp)
  2. 花在内存访问上的时间(Tmem)

通常,剖析器提供函数花费的总时间的估计。 是否有可能估算出上述两个组件(Tcomp和Tmem)所花费的时间?

Roofline模型提出了算术强度的概念: https ://crd.lbl.gov/departments/computer-science/PAR/research/roofline/。 简单地说它定义了为每次内存访问执行的算术指令的数量。

计算算术强度通常通过使用性能计数器来实现。

不可能测量这个(并且没有任何意义),因为计算与当前处理器体系结构中的存储器访问重叠。 此外,访问存储器通常分解为更多步骤(访问存储器,预取到各种高速缓存级别,实际读取到处理器寄存器)。

您可以使用perf及其硬件计数器(如果您的硬件支持)来测量各种缓存级别上的缓存命中和未命中,以估计算法在硬件上的效率。

Brendan Gregg在他最近的博客文章“ CPU利用率错误”中建议每个周期使用PMC指令。 简而言之,如果IPC <1.0,那么app可以被视为内存限制。 否则可以将其视为指令限制。 以下是他的帖子的相关摘录:

如果你的IPC <1.0,你可能会停止内存,软件调优策略包括减少内存I / O,改善CPU缓存和内存局部性,尤其是在NUMA系统上。 硬件调优包括使用具有更大CPU缓存的处理器,以及更快的内存,总线和互连。

如果你的IPC> 1.0,你可能会被指令限制。 寻找减少代码执行的方法:消除不必要的工作,缓存操作等.CPU火焰图是这项调查的一个很好的工具。 对于硬件调优,请尝试更快的时钟速率,以及更多内核/超线程。

对于我的上述规则,我分为IPC 1.0。 我从哪里得到的? 根据我之前与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

如果你正在寻找一个获得CPU周期的功能,那么boost将非常有帮助。 我使用Boost Timer Utility来计算系统调用的cpu周期。

另一方面,您可以在完整程序上放置相同的功能以获得总时间。

我希望这就是你要找的东西。 -Vijay

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM