我一直在寻找一种方法来找出我的计划花费时间的地方。我读了perf tutorial并尝试描述那里描述的睡眠时间。我写了最简单的程序来分析:
#include <unistd.h>
int main() {
sleep(10);
return 0;
}
然后我用perf:
执行它$ sudo perf record -e sched:sched_stat_sleep -e sched:sched_switch -e sched:sched_process_exit -g -o ~/perf.data.raw ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.013 MB /home/pablo/perf.data.raw (~578 samples) ]
$ sudo perf inject -v -s -i ~/perf.data.raw -o ~/perf.data
build id event received for [kernel.kallsyms]: d62870685909222126e7070d2bafdf029f7ed3b6
failed to write feature 2
$ sudo perf report --stdio --show-total-period -i ~/perf.data
Error:
The /home/pablo/perf.data file has no samples!
有人知道如何避免这些错误吗?他们的意思是什么? failed to write feature 2
看起来不太友好......
更新:
$ uname -a
Linux debian 3.12-1-amd64 #1 SMP Debian 3.12.9-1 (2014-02-01) x86_64 GNU/Linux
答案 0 :(得分:11)
来自https://perf.wiki.kernel.org/index.php/Tutorial#Profiling_sleep_times - perf inject -s
$ sudo perf inject -v -s -i ~/perf.data.raw -o ~/perf.data
build id event received for [kernel.kallsyms]: d62870685909222126e7070d2bafdf029f7ed3b6
failed to write feature 2
未能写入功能2看起来不太用户友好......
...但它被添加到perf以使错误更加用户友好:http://lwn.net/Articles/460520/“perf:make perf.data更具自我描述性(v5)”作者:Stephane Eranian,2011年9月22日:
+static int do_write_feat(int fd, struct perf_header *h, int type, ....
+ pr_debug("failed to write feature %d\n", type);
此处列出了所有功能http://lxr.free-electrons.com/source/tools/perf/util/header.h#L13
15 HEADER_TRACING_DATA = 1,
16 HEADER_BUILD_ID,
因此,如果我没有错的话,听起来像perf inject无法写入有关构建ID的信息(来自util / header.c的函数write_build_id()
的错误)。有两种情况可能导致错误:调用perf_session__read_build_ids()
失败或编写buildid表dsos__write_buildid_table
失败(这不是我们的情况,因为没有“写入buildid表失败”错误消息;请检查write_build_id
)
您可以检查,您是否拥有会话所需的所有构建。清除buildid缓存(rm -rf ~/.debug
)并检查是否有最新的vmlinux,并在内核中启用调试信息或kallsyms可能很有用。
更新: Pavel说他的pref记录没有写入perf.data的sched:sched_stat_sleep
个事件:
sudo perf record -e sched:sched_stat_sleep -e sched:sched_switch -e sched:sched_process_exit -g -o ~/perf.data.raw ./a.out
正如他在his answer中解释的那样,他的默认debian内核已禁用CONFIG_SCHEDSTATS
选项与供应商的补丁。自3.11以来,redhat对发布内核中的选项做了同样的事情,这在Redhat Bug 1013225中有解释(Josh Boyer 2013-10-28,评论4):
我们切换到仅在调试构建之前启用。它似乎完全被最终的3.11.0版本所关闭,并一直保持关闭。内部测试显示该选项对上下文切换具有非平凡的性能影响。
我们可以再次在调试内核中打开它,但我不确定它是否值得。
Josh Poimboeuf 2013-11-04在评论8中表示可以检测到性能影响:
在我的测试中,我在各种CPU负载下做了很多上下文切换。启用CONFIG_SCHEDSTATS时,我看到平均上下文切换速度下降了约5-10%。 ...性能影响似乎只发生在CFS后的内核上(&gt; = 2.6.23)。以前的O(1)调度程序似乎没有这个问题。
Fedora于2013年7月12日在Dave Jones的非调试内核中禁用了CONFIG_SCHEDSTAT "[kernel] Disable LATENCYTOP/SCHEDSTATS in non-debug builds."。第一个带有禁用选项的内核:3.11.0-0.rc0.git6.4。
为了使用名称为perf
(sched:sched_stat_*
,sched:sched_stat_wait
,sched:sched_stat_sleep
)的任何sched:sched_stat_iowait
软件跟踪点事件,我们必须重新编译内核启用CONFIG_SCHEDSTATS
选项并替换没有此选项的默认Debian,RedHat或Fedora内核。
谢谢Pavel Davydov。
答案 1 :(得分:7)
我终于找到了如何让它发挥作用。问题是默认的debian内核是在没有一些配置选项的情况下构建的,perf需要能够监控休眠时间。看起来应该启用CONFIG_SCHEDSTATS
来生成内核收集调度程序统计信息。这被告知有一些运行时开销。我还启用了CONFIG_SCHED_TRACER
和一些锁定跟踪选项,但我不确定它们在我的情况下是否重要。无论如何,没有CONFIG_SCHEDSTATS
的调度程序中没有收集统计数据(参见内核源代码的kernel/sched/
目录)。
此外,Brendan Gregg撰写了一篇非常good article about perf的文章,其中包含大量有用的示例和一些内核选项,可以使perf正常工作。
更新:我在debian中查看了CONFIG_SCHEDSTATS的历史记录。我查看了debian内核补丁并构建了脚本repo:
svn checkout svn://svn.debian.org/svn/kernel/dists/trunk/linux/debian
然后在那里找到CONFIG_SCHEDSTATS选项
$ grep -R CONFIG_SCHEDSTAT config/
config/config:# CONFIG_SCHEDSTATS is not set
此字符串已添加到2008年3月14日的提交10837中的repo中,注释为“debian / config:Do complete reorganization”。此外,在this和this(感谢 osgx )错误报告中,它被告知CONFIG_LATENCYTOP,CONFIG_SCHEDSTATS选项未启用,因为它们可能会影响内核性能。所以,我认为它从未在默认的debian内核中打开。但是,我还没有找到关于调度程序统计选项的讨论。如果我这样做,我会在这里回信。
答案 2 :(得分:1)
这适用于“openSUSE 13.1(x86_64)”框中的“perf版本3.11.1”。
如果你关心,这是输出:
# ========
# captured on: Sun Feb 16 09:49:38 2014
# hostname : *****************
# os release : 3.11.10-7-desktop
# perf version : 3.11.1
# arch : x86_64
# nrcpus online : 8
# nrcpus avail : 8
# cpudesc : Intel(R) Core(TM) i7-3840QM CPU @ 2.80GHz
# cpuid : GenuineIntel,6,58,9
# total memory : 32945368 kB
# cmdline : /usr/bin/perf inject -v -s -i perf.data.raw -o perf.data
# event : name = sched:sched_stat_sleep, type = 2, config = 0x48, config1 = 0x0, config2 = 0x
# event : name = sched:sched_switch, type = 2, config = 0x51, config1 = 0x0, config2 = 0x0, e
# event : name = sched:sched_process_exit, type = 2, config = 0x4e, config1 = 0x0, config2 =
# HEADER_CPU_TOPOLOGY info available, use -I to display
# HEADER_NUMA_TOPOLOGY info available, use -I to display
# pmu mappings: cpu = 4, software = 1, tracepoint = 2, uncore_cbox_0 = 6, uncore_cbox_1 = 7,
# ========
#
# Samples: 0 of event 'sched:sched_stat_sleep'
# Event count (approx.): 0
#
# Overhead Period Command Shared Object Symbol
# ........ ............ ....... ............. ......
#
# Samples: 8 of event 'sched:sched_switch'
# Event count (approx.): 80099958776
#
# Overhead Period Command Shared Object Symbol
# ........ ............ ....... ................. .................
#
100.00% 80099958776 bla [kernel.kallsyms] [k] thread_return
|
--- thread_return
thread_return
do_nanosleep
hrtimer_nanosleep
SyS_nanosleep
system_call_fastpath
0x7fbc0dec6570
__GI___libc_nanosleep
(nil)
# Samples: 0 of event 'sched:sched_process_exit'
# Event count (approx.): 0
#
# Overhead Period Command Shared Object Symbol
# ........ ............ ....... ............. ......
#
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
}