我知道有一些工具,如顶部和 ps 来衡量CPU使用率,但他们测量CPU使用率的方式是通过测量空闲任务的时间长短没跑因此,例如,即使CPU由于高速缓存未命中而导致停顿,这些工具仍将认为CPU被占用。但是,我想要的是分析工具在停顿期间将CPU视为空闲。是否有任何工具可以做到这一点?
答案 0 :(得分:6)
用于测量CPU使用率的top和ps等工具,...测量CPU使用率是通过测量空闲任务未运行的时间。
不,他们没有测量空闲,他们只是通过/ proc / stat(也尝试vmstat 1
工具)读取内核对其CPU使用率的看法。您是否检查过系统范围的用户+系统时间仅由idle
计算?我认为,内核只会导出一些调度程序的统计信息,它会在重新安排时记录用户/系统状态,包括系统计时器和阻塞系统调用(可能是cpuacct_charge
的一个调用者,如update_curr
- 更新当前任务的运行时统计信息。)。
/ proc / stat示例:
cat /proc/stat
cpu 2255 34 2290 22625563 6290 127 456
并按http://www.linuxhowtos.org/System/procstat.htm
解码第一个“cpu”行聚合所有其他“cpuN”行中的数字。这些数字表示CPU执行不同类型工作所花费的时间。时间单位为USER_HZ或 Jiffies (通常为百分之一秒)。
列的含义如下,从左到右:
user: normal processes executing in user mode
nice: niced processes executing in user mode
system: processes executing in kernel mode
idle: twiddling thumbs
当我们听到jiffie时,这意味着调度程序用于获取数字,而不是估计idle
任务(顶部甚至看不到此任务或任务带有pid 0)。
因此,例如,即使CPU由于高速缓存未命中而导致停顿,这些工具仍会认为CPU被占用。
基本上(当没有SMT时,就像英特尔中的HT一样),当你的任务由于内存访问而导致管道停顿(或采用无序的错误路径)时,CPU就会被占用。操作系统无法运行其他任务,因为任务切换比等待这一档更加昂贵。
SMT的情况不同,因为有硬件可以在单个硬件上切换两个逻辑任务,甚至(在细粒度SMT中)将其指令(微操作)混合到单个流中以在共享硬件上执行。通常有SMT统计计数器来检查实际混合。
但是,我想要的是分析工具在停顿期间将CPU视为空闲。是否有任何工具可以做到这一点?
性能监控单元可能会为此提供有用的事件。例如,perf stat
报告一些(在Sandy Bridge上)
$ perf stat /bin/sleep 10
Performance counter stats for '/bin/sleep 10':
0,563759 task-clock # 0,000 CPUs utilized
1 context-switches # 0,002 M/sec
0 CPU-migrations # 0,000 M/sec
175 page-faults # 0,310 M/sec
888 767 cycles # 1,577 GHz
568 603 stalled-cycles-frontend # 63,98% frontend cycles idle
445 567 stalled-cycles-backend # 50,13% backend cycles idle
593 103 instructions # 0,67 insns per cycle
# 0,96 stalled cycles per insn
115 709 branches # 205,246 M/sec
7 699 branch-misses # 6,65% of all branches
10,000933734 seconds time elapsed
所以,它说睡眠10使用了0,5 jiffie(任务时钟)。它太低了,无法计入经典的rusage,并且/ usr / bin / time得到0 jiffie作为任务CPU使用率(用户+系统): $ / usr / bin / time sleep 10 0.00user 0.00system 0:10.00elapsed 0%CPU(0avgtext + 0avgdata 2608maxresident)k 0inputs + 0outputs(0major + 210minor)pagefaults 0swaps
然后执行测量(在PMU的帮助下计数)实际循环和由任务执行的实际指令(以及代表任务的内核) - cycles
和instructions
行。睡眠已经使用了888k个周期,但只完成了593k个有用的指令,平均值IPC为0.6-0.7(30-40%的停顿)。失去了大约300k个周期;并在Sandy bridge perf
上报告它们丢失的位置 - stalled-cycles-*
前端事件(解码器 - CPU不知道由于分支未命中或由于未预取到L1I的代码而执行什么)以及后端(无法执行,因为指令需要来自内存的某些数据,这些数据在正确的时间不可用 - 内存停顿)。
为什么我们在没有执行任何指令的情况下应该只有300k个周期时看到CPU内部有更多停顿?这是因为现代处理器通常超标量且无序 - 它们可以在每个CPU时钟周期开始执行多个指令,甚至可以对它们进行重新排序。如果您想查看执行端口利用率,请尝试使用Andi Kleen的pmu-tools中的ocperf
(perf wrapper)和一些有关其PMU计数器的英特尔手册。还有toplev.py
脚本“识别工作负载的微架构瓶颈”,而无需手动选择英特尔事件。