如何分析C/ c++应用程序中内存访问所花费的时间
How to profile time spent in memory access in C/C++ applications?
应用程序中一个函数所花费的总时间大致可以分为两个部分:
- 实际计算时间(Tcomp)
- 内存访问时间(Tmem)
通常,分析器提供一个函数所花费的总时间的估计。是否有可能根据上述两个组件(Tcomp和Tmem)估算所花费的时间?
算术强度的概念已由rooline模型提出:https://crd.lbl.gov/departments/computer-science/PAR/research/roofline/。简单地说,它定义了每次访问内存时执行的算术指令的数量。
计算算术强度通常通过使用性能计数器来实现。
Brendan Gregg在他最近的博客文章《CPU利用率是错误的》中建议使用每周期PMC指令。简而言之,如果IPC是<1.0以上的应用可以被认为是内存受限的。否则,它可以被认为是指令边界。以下是他文章中的相关节选:
如果你的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
不可能测量这一点(这样做没有任何意义),因为计算与当前处理器体系结构中的内存访问重叠。此外,访问内存通常被分解为多个步骤(访问内存,预取到各种缓存级别,实际读取到处理器寄存器)。
您可以使用perf及其硬件计数器(如果您的硬件支持)测量不同缓存级别上的缓存命中和未命中,以估计您的算法在硬件上的效率。
如果您正在寻找一个函数来获得CPU周期,那么boost将非常有帮助。我已经使用Boost Timer实用程序来计算系统调用的cpu周期。
另一方面,您可以将相同的函数放在完整的程序中以获得总体时间。
我希望这是你正在寻找的。vijay
- 特里树.无法访问内存
- 如何使用 C/C++ 访问内存的内容?
- 指针可以用于访问内存中的任何任意区域吗?
- 分段错误:无法访问内存
- SIGABRT 在线程中访问内存时
- 访问内存以内联循环访问数组
- 如何从C或C 语言级别安全访问内存映射的硬件寄存器
- 在释放了所有作用域内指针之后仍然可访问内存
- 有什么快速访问内存的技巧吗
- CUDA非法访问内存
- C++ 访问内存冲突
- 悬空指针仍在访问内存值
- 当我尝试从结构列表中访问内存时出现错误:" Program received signal SIGSEGV, Segmentation fault."
- 如何访问内存映射的 USB 主控制器寄存器
- 访问内存时出现奇怪的崩溃
- 如何在C++读取块后访问内存中的文件数据
- 使用共享库时仍可访问内存
- 从 C++ 结构中包含的指针数组动态分配和访问内存
- Win32应用程序,可无限制地访问内存
- 强制两个线程直接访问内存中的全局变量