13

我尝试使用 valgrind 分析一个简单的 c prog:

[zsun@nel6005001 ~]$ valgrind --tool=memcheck ./fl.out
==2238== Memcheck,内存错误检测器
==2238== 版权所有 (C) 2002-2009 和 GNU GPL'd,由 Julian西沃德等人。
==2238== 使用 Valgrind-3.5.0 和 LibVEX;使用 -h 重新运行版权信息
==2238== 命令:./fl.out
==2238==
==2238==
==2238== HEAP 摘要:
==2238== 退出时使用:1,168 字节1 个块
==2238== 总堆使用量:1 个分配,0 个释放,分配 1,168 个字节
==2238==
==2238== 泄漏摘要:
==2238== 肯定丢失:0 个块中的 0 个字节
==2238= = 间接丢失:0 个块中的 0 个字节
==2238== 可能丢失:0 个块中的 0 个字节
==2238== 仍然可以访问:1 个块中的 1,168 个字节
==2238== 抑制:0 个块中的 0 个字节
==2238== 使用 --leak-check=full 重新运行以查看泄漏内存的详细信息
==2238==
==2238== 对于检测到和抑制的错误计数,重新运行:-v
==2238== 错误摘要:0 个上下文中的 0 个错误(抑制:8 个中的 12 个)
分析计时器已过期

我试图分析的 c 代码如下:

void forloop(void){
    int fac=1;
    int count=5;
    int i,k;

    for (i = 1; i <= count; i++){
        for(k=1;k<=count;k++){
            fac = fac * i;
        }
    }
}

显示“分析计时器已过期”,这是什么意思?如何解决这个问题呢?谢谢!

4

3 回答 3

23

问题是您在使用-pg. 您不能同时使用 valgrind 和 gprof。如果您在 Linux 上并且需要在 valgrind 下分析程序的实际仿真,则 valgrind 手册建议使用 OProfile。

于 2010-01-27T19:17:36.057 回答
1

顺便说一句,这不是计算阶乘。

如果你真的想知道时间都去哪儿了,你可以试试stackshots。我在您的代码周围放置了一个无限循环并取了其中的 10 个。这是代码:

 6: void forloop(void){ 
 7:   int fac=1; 
 8:   int count=5; 
 9:   int i,k; 
10:
11:   for (i = 1; i <= count; i++){ 
12:       for(k=1;k<=count;k++){ 
13:           fac = fac * i; 
14:       } 
15:   } 
16: } 
17:
18: int main(int argc, char* argv[])
19: {
20: int i;
21: for (;;){
22:     forloop();
23: }
24: return 0;
25: }

以下是堆栈截图,重新排序,最频繁的在顶部:

forloop() line 12
main() line 23

forloop() line 12 + 21 bytes
main() line 23

forloop() line 12 + 21 bytes
main() line 23

forloop() line 12 + 9 bytes
main() line 23

forloop() line 13 + 7 bytes
main() line 23

forloop() line 13 + 3 bytes
main() line 23

forloop() line 6 + 22 bytes
main() line 23

forloop() line 14
main() line 23

forloop() line 7
main() line 23

forloop() line 11 + 9 bytes
main() line 23

这告诉你什么?它说第 12 行消耗了大约 40% 的时间,而第 13 行消耗了大约 20% 的时间。它还告诉您第 23 行消耗了几乎 100% 的时间。

这意味着在第 12 行展开循环可能会给您带来大约 100/(100-40) = 100/60 = 1.67 倍的加速因子。当然,如果您真的想计算阶乘,还有其他方法可以加快此代码的速度,例如消​​除内部循环。

我只是指出这一点,因为这是一种非常简单的分析方法。

于 2010-02-03T16:02:06.553 回答
0

你将无法10000!像那样计算。您将需要某种bignum实现来计算阶乘。这是因为int“通常”是 4 个字节长,这意味着“通常”它可以容纳2^32 - 1(signed int, 2^31) -13!不止于此。即使您使用了unsigned long(“通常”8 个字节),当您到达21!.

至于“分析计时器已过期”的含义 - 这意味着 valgrind 收到了信号SIGPROFhttp ://en.wikipedia.org/wiki/SIGPROF (可能意味着您的程序花费了太长时间)。

于 2010-01-27T10:45:28.120 回答