如何修改C程序以便gprof可以对其进行配置?
当我在我的C程序上运行gprof时,它表示没有为我的程序累积时间,并显示所有函数调用都为0。 但它确实计数了函数调用。
如何修改我的程序,以便gprof能够计算需要运行多少时间?
编译时是否指定了-pg?
http://sourceware.org/binutils/docs-2.20/gprof/Compiling.html#Compiling
编译完成后,运行该程序,然后在二进制文件上运行gprof。
例如:
test.c的:
#include <stdio.h>
int main ()
{
int i;
for (i = 0; i < 10000; i++) {
printf ("%dn", i);
}
return 0;
}
编译为cc -pg test.c
,然后以a.out
运行,然后运行gprof a.out
,给我
granularity: each sample hit covers 4 byte(s) for 1.47% of 0.03 seconds % cumulative self self total time seconds seconds calls ms/call ms/call name 45.6 0.02 0.02 10000 0.00 0.00 __sys_write [10] 45.6 0.03 0.02 0 100.00% .mcount (26) 2.9 0.03 0.00 20000 0.00 0.00 __sfvwrite [6] 1.5 0.03 0.00 20000 0.00 0.00 memchr [11] 1.5 0.03 0.00 10000 0.00 0.00 __ultoa [12] 1.5 0.03 0.00 10000 0.00 0.00 _swrite [9] 1.5 0.03 0.00 10000 0.00 0.00 vfprintf [2]
你有什么?
我尝试运行Kinopiko的例子,除了我将迭代次数增加了100倍。
test.c的:
#include <stdio.h>
int main ()
{
int i;
for (i = 0; i < 1000000; i++) {
printf ("%dn", i);
}
return 0;
}
然后我拿了10张stackshot(在VC下,但你可以使用pstack )。 这里是stackshots:
9 copies of this stack:
NTDLL! 7c90e514()
KERNEL32! 7c81cbfe()
KERNEL32! 7c81cc75()
KERNEL32! 7c81cc89()
_write() line 168 + 57 bytes
_flush() line 162 + 23 bytes
_ftbuf() line 171 + 9 bytes
printf() line 62 + 14 bytes
main() line 7 + 14 bytes
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 7c817077()
1 copy of this stack:
KERNEL32! 7c81cb96()
KERNEL32! 7c81cc75()
KERNEL32! 7c81cc89()
_write() line 168 + 57 bytes
_flush() line 162 + 23 bytes
_ftbuf() line 171 + 9 bytes
printf() line 62 + 14 bytes
main() line 7 + 14 bytes
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 7c817077()
如果不明显,这告诉你:
mainCRTStartup() line 206 + 25 bytes Cost ~100% of the time
main() line 7 + 14 bytes Cost ~100% of the time
printf() line 62 + 14 bytes Cost ~100% of the time
_ftbuf() line 171 + 9 bytes Cost ~100% of the time
_flush() line 162 + 23 bytes Cost ~100% of the time
_write() line 168 + 57 bytes Cost ~100% of the time
简而言之,程序花费大约100%的时间清理磁盘(或控制台)输出缓冲区,作为第7行printf的一部分。
(我的意思是“一条线的成本”是 - 这个线的要求花费的总时间的一小部分,这大约是包含它的样本的一小部分,如果这条线可以花时间,例如删除它,跳过它或将其工作交给一个无限快速的协处理器,这个时间部分就是总时间会缩短多少,所以如果能够避免执行任何这些代码行,在95%到100%的范围内缩小,如果你问“递归怎么办?”,答案是“ 它没有区别”。 )
现在,也许你想知道别的东西,比如说在循环中花了多少时间。 要发现这一点,请删除printf,因为它一直在占用。 也许你想知道纯粹CPU时间花费的时间百分比,而不是系统调用。 为了达到这个目的,只需扔掉任何不会在代码中结束的stackshot。
我试图提出的一点是,如果你正在寻找可以修复的东西来使代码运行得更快,那么即使你理解它,数据gprof也会给你带来几乎无用的结果。 相比之下,如果有一些代码会导致更多的时钟花费在您想要的时间之外,那么stackshots会查明它。
一个gprof
:它不适用于动态链接库中的代码。 为此,您需要使用sprof
。 看到这个答案:gprof:如何为链接到主程序的共享库中的函数生成调用图
上一篇: How to modify a C program so that gprof can profile it?