我今天尝试了linux的perf实用程序,但在解释其结果方面遇到了麻烦.我已经习惯了valgrind的callgrind,这当然是一种完全不同于基于采样的perf方法的方法.
我做了什么:
perf record -g -p $(pidof someapp)
perf report -g -n
Run Code Online (Sandbox Code Playgroud)
现在我看到这样的事情:
+ 16.92% kdevelop libsqlite3.so.0.8.6 [.] 0x3fe57 ? + 10.61% kdevelop libQtGui.so.4.7.3 [.] 0x81e344 ? + 7.09% kdevelop libc-2.14.so [.] 0x85804 ? + 4.96% kdevelop libQtGui.so.4.7.3 [.] 0x265b69 ? + 3.50% kdevelop libQtCore.so.4.7.3 [.] 0x18608d ? + 2.68% kdevelop libc-2.14.so [.] memcpy ? + 1.15% kdevelop [kernel.kallsyms] [k] copy_user_generic_string ? + 0.90% kdevelop libQtGui.so.4.7.3 [.] QTransform::translate(double, double) ? + 0.88% kdevelop libc-2.14.so [.] __libc_malloc ? + …
根据perf教程,perf stat应该使用硬件计数器报告缓存未命中.但是,在我的系统(最新的Arch Linux)上,它没有:
[joel@panda goog]$ perf stat ./hash
Performance counter stats for './hash':
869.447863 task-clock # 0.997 CPUs utilized
92 context-switches # 0.106 K/sec
4 cpu-migrations # 0.005 K/sec
1,041 page-faults # 0.001 M/sec
2,628,646,296 cycles # 3.023 GHz
819,269,992 stalled-cycles-frontend # 31.17% frontend cycles idle
132,355,435 stalled-cycles-backend # 5.04% backend cycles idle
4,515,152,198 instructions # 1.72 insns per cycle
# 0.18 stalled cycles per insn
1,060,739,808 branches # 1220.015 M/sec
2,653,157 branch-misses # 0.25% of …Run Code Online (Sandbox Code Playgroud) Linux perf工具(前一段时间命名perf_events)有几个内置的通用软件事件.其中最基本的两个是:task-clock和cpu_clock(内部称为PERF_COUNT_SW_CPU_CLOCK和PERF_COUNT_SW_TASK_CLOCK).但他们的错误在于缺乏描述.
ysdx用户报告说man perf_event_open有简短的描述:
PERF_COUNT_SW_CPU_CLOCK
This reports the CPU clock, a high-resolution per-
CPU timer.
PERF_COUNT_SW_TASK_CLOCK
This reports a clock count specific to the task
that is running.
Run Code Online (Sandbox Code Playgroud)
但描述很难理解.
有人可以提供有关如何以及何时权威的答案task-clock和cpu-clock事件都占?它们与linux内核调度程序有什么关系?
当task-clock并cpu-clock会给出不同的价值观?我应该使用哪一个?
我需要"perf"实用程序来监控我的Mac上的程序.我知道linux附带了它,但它可以在Mac上使用吗?
我正在研究OSX 10.9 Mavericks并尝试使用perf或linux工具进行"端口搜索",但我无法获得任何结果.
我试图弄清楚为什么修改后的C程序比未修改的计数器部分运行得更快(我添加了很少的代码行来执行一些额外的工作).在这种情况下,我怀疑" 缓存效应 "是主要的解释(指令缓存).因此,我到达perf(https://perf.wiki.kernel.org/index.php/Main_Page)分析工具,但遗憾的是我无法理解其有关缓存未命中的输出的含义.
提供了几个关于缓存的事件:
cache-references [Hardware event]
cache-misses [Hardware event]
L1-dcache-loads [Hardware cache event]
L1-dcache-load-misses [Hardware cache event]
L1-dcache-stores [Hardware cache event]
L1-dcache-store-misses [Hardware cache event]
L1-dcache-prefetches [Hardware cache event]
L1-dcache-prefetch-misses [Hardware cache event]
L1-icache-loads [Hardware cache event]
L1-icache-load-misses [Hardware cache event]
L1-icache-prefetches [Hardware cache event]
L1-icache-prefetch-misses [Hardware cache event]
LLC-loads [Hardware cache event]
LLC-load-misses [Hardware cache event]
LLC-stores [Hardware cache event]
LLC-store-misses [Hardware cache event]
LLC-prefetches [Hardware cache event]
LLC-prefetch-misses [Hardware cache event]
dTLB-loads [Hardware cache event] …Run Code Online (Sandbox Code Playgroud) 例如,
def test():
print "test"
Run Code Online (Sandbox Code Playgroud)
我用过perf record -g -p $pid,但结果只是一切PyEval_EvalFrameEx.如何才能获得真实姓名"test"或者如果不能使用perf?
跑步perf stat ls显示:
Performance counter stats for 'ls':
1.388670 task-clock # 0.067 CPUs utilized
2 context-switches # 0.001 M/sec
0 cpu-migrations # 0.000 K/sec
266 page-faults # 0.192 M/sec
3515391 cycles # 2.531 GHz
2096636 stalled-cycles-frontend # 59.64% frontend cycles idle
<not supported> stalled-cycles-backend
2927468 instructions # 0.83 insns per cycle
# 0.72 stalled cycles per insn
615636 branches # 443.328 M/sec
22172 branch-misses # 3.60% of all branches
0.020657192 seconds time elapsed
Run Code Online (Sandbox Code Playgroud)
为什么stalled-cycles-backend显示为"不支持"?我需要什么样的CPU,硬件,内核或用户空间软件才能看到这个值?
目前从事Linux 3.12试过这种对RHEL的x86_64的,相匹配的"PERF"版本,在不同的英特尔酷睿i5和i7系统(Ivy Bridge的类型).他们都没有支持陷入停滞的周期后端.
更多信息: …
使用时perf report,我没有看到我的程序的任何符号,而是我得到这样的输出:
$ perf record /path/to/racket ints.rkt 10000
$ perf report --stdio
# Overhead Command Shared Object Symbol
# ........ ........ ................. ......
#
70.06% ints.rkt [unknown] [.] 0x5f99b8
26.28% ints.rkt [kernel.kallsyms] [k] 0xffffffff8103d0ca
3.66% ints.rkt perf-32046.map [.] 0x7f1d9be46650
Run Code Online (Sandbox Code Playgroud)
这是相当缺乏信息的.
相关程序使用调试符号构建,sysprof工具显示相应的符号,Zoom也是如此,我认为它是perf在引擎盖下使用的.
请注意,这是在x86-64上,因此二进制文件是使用编译的-fomit-frame-pointer,但在其他工具下运行时也是这种情况.
我正在以下列方式运行"perf":
perf record -a --call-graph -p some_pid
perf report --call-graph --stdio
Run Code Online (Sandbox Code Playgroud)
然后,我看到了这个:
1.60% my_binary my_binary [.] my_func
|
--- my_func
|
|--71.10%-- (nil)
| (nil)
|
--28.90%-- 0x17f310000000a
Run Code Online (Sandbox Code Playgroud)
我看不出哪个函数调用my_func().我看到"nil"和"0x17f310000000a".难道我做错了什么?这可能不是调试信息问题,因为显示了一些符号而其他符号未显示.
更多信息:
我编译perf了我的内核(3.11.10).在编译期间,一些库丢失了,所以我安装了这些库.
但是现在当我跑步时perf,我得到以下信息:
Couldn't record kernel reference relocation symbol
Symbol resolution may be skewed if relocation was used (e.g. kexec).
Check /proc/kallsyms permission or run as root.
Kernel address maps (/proc/{kallsyms,modules}) were restricted.
Check /proc/sys/kernel/kptr_restrict before running 'perf record'
If some relocation was applied (e.g. kexec) symbols may be misresolved.
Samples in kernel modules can't be resolved as well.
Run Code Online (Sandbox Code Playgroud)
由于我使用的是自定义构建内核,对我来说最明显的解释是,我的内核缺少某些选项.如果是这样,我怎样才能找出遗漏的内容?
我不确定到底perf在抱怨什么.我怎样才能解决这个问题?
编辑:
/proc/kallsyms不存在并/proc/sys/kernel/kptr_restrict包含0:
$ cat /proc/sys/kernel/kptr_restrict
0
Run Code Online (Sandbox Code Playgroud)
我自己编译了内核,它可能缺少一些选项.这是什么/proc/kallsyms?如何在我的内核中启用它?
perf ×10
linux ×7
profiling ×4
performance ×3
c ×1
c++ ×1
caching ×1
cpu ×1
kernel ×1
linux-kernel ×1
macos ×1
optimization ×1
python ×1
scheduler ×1