让 gprof 根据挂钟时间进行分析?
我的理解是,默认情况下 gprof 会考虑 CPU 时间。有没有办法让它根据挂钟时间进行分析?
我的程序执行大量磁盘 I/O,因此它使用的 CPU 时间仅代表实际执行时间的一小部分。我需要知道磁盘 I/O 的哪些部分占用最多时间。
My understanding is that by default gprof takes into account CPU time. Is there a way to get it to profile based on wall-clock time?
My program does a lot of disk i/o, so the CPU time it uses only represents a fraction of the actual execution time. I need to know which portions of the disk i/o take up the most time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
gprof 不会这样做。
看看这个。
这个。
还有 简而言之:在 gdb 下,运行它并随机执行 Ctrl-Break 或 Ctrl-C 10 次,并显示调用堆栈。如果您的 I/O 占用了(例如)60% 的时间,那么(大约)每 10 次暂停中有 6 次,您将在 writebuf 或 readbuf 例程中看到它,并且请求 I/O 的代码行将在清楚地显示在堆栈上。
您还可以使用lsstack来获取相同的信息。
gprof won't do this.
Look at this.
And this.
In a nutshell: Under gdb, get it running and do Ctrl-Break or Ctrl-C 10 times at random, and display the call stack. If your I/O is taking (for example) 60% of the time, then on (roughly) 6 out of 10 pauses, you will see it in the writebuf or readbuf routine, and the lines of code requesting that I/O will be clearly displayed on the stack.
You could also use lsstack to get the same information.
您可以使用 strace 或 cachegrind 来正确分析代码。 strace 将为您提供系统调用所花费时间的详细信息,cachegrind 将为您提供资源利用率的详细分析。
You can use strace or cachegrind to profile the code properly. strace will give you details of time spent in system calls and cachegrind will give detailed analysis of resource utilization.
更改 gprof 来进行挂钟分析非常容易。唯一需要替换的 8 个字符是:
在文件
glibc/sysdeps/posix/profil.c
中,函数__profil
,靠近setitimer
的调用和sigaction
(更准确的__Setitimer
和__sigaction
)更改后,任何使用 SIGALRM 的程序都将被破坏,并且任何没有阻塞系统调用的程序重新启动代码可能会给出错误的结果。
另外,您可以直接更改 glibc 二进制文件中的 int 值(请不要在系统范围的 libc.so 上执行此操作,制作单独的副本并将其通过 LD_LIBRARY_PATH 提供给程序)
对于二进制补丁,ITIMER_PROF 是2; ITIMER_REAL 为 0; SIGPROF 为 27 (0x1b); SIGALRM 为 14 (0x0e)。 glibc 的函数
profile
中每个常量有两个位置。另一种方法是编写一个 ptrace 调试器,它将在运行时更改 setitimer 和 sigaction 函数的参数。
It is very easy to change gprof to do wall-clock profiling. The only 8 chars to replace are:
in the file
glibc/sysdeps/posix/profil.c
, function__profil
, near the calls tosetitimer
andsigaction
(more exact__Setitimer
and__sigaction
)After the change any program which uses SIGALRM will be broken and any program which have no blocking-syscall restarting code can give wrong results.
Also, you can directly change int values in glibc binary (please, dont do this on system wide
libc.so
, make a separate copy and give it to the program with LD_LIBRARY_PATH)For binary patch, ITIMER_PROF is 2; ITIMER_REAL is 0; SIGPROF is 27 (0x1b); SIGALRM is 14 (0x0e). There are two places for each constant in function
profil
of glibc.Another way is to write a ptrace-debugger, which will change arguments of setitimer and sigaction functions at run-time.
您可以使用 gcc 编译器的
-finstrument-functions
选项来执行此操作。这将在任何函数的入口/出口点调用一个自定义函数,只需要提供几个函数回调(__cyg_profile_func_enter
和__cyg_profile_func_exit
)。您可以通过查找 gcc 手册中的
-finstrument-functions
选项来找到更多详细信息。Balau 的技术博客上还有一篇很好的文章,提供了端到端概述/示例,说明其工作原理:使用 GCC 跟踪和分析函数调用
You can do this using the
-finstrument-functions
option with the gcc compiler. That will get a custom function called at entry/exit point of any function, just need to provide a couple of function callbacks (__cyg_profile_func_enter
and__cyg_profile_func_exit
).You can find more details by looking up the
-finstrument-functions
option in the gcc manual.There is also a good post on Balau's technical blog that provides an end to end overview/example of how this works: Trace and profile function calls with GCC
您可以使用 google-perftools 中的分析器来测量挂钟时间。要将 google profiler 切换到挂钟模式,请设置环境变量 CPUPROFILE_REALTIME=1。
You can measure wall-clock time by using profiler from google-perftools. To switch google profiler to wall-clock mode, set the environment variable CPUPROFILE_REALTIME=1.