【问题标题】:valgrind, profiling timer expired?valgrind,分析计时器已过期?
【发布时间】:2011-01-09 21:43:46
【问题描述】:

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

[zsun@nel6005001 ~]$ valgrind --tool=memcheck ./fl.out
==2238== Memcheck,内存错误检测器
==2238== 版权所有 (C) 2002-2009 和 GNU GPL,由 Julian Seward 等人提供。
==2238== 使用 Valgrind-3.5.0 和 LibVEX;使用 -h 重新运行以获取版权信息
==2238== 命令:./fl.out
==2238==
==2238==
==2238== 堆摘要:
==2238== 在退出时使用:1 个块中的 1,168 个字节
==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;
        }
    }
}

出现“Profiling timer expired”,这是什么意思?如何解决这个问题呢?谢谢!

【问题讨论】:

    标签: valgrind


    【解决方案1】:

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

    【讨论】:

    • valgrind memcheck 检测内存错误,gprof 和 oprofile 帮助发现性能问题。您不能同时使用 gprof 和 valgrind,除非您正在研究 valgrind 本身或其工具之一的性能,否则它不会那么有用。如果你想检查内存错误并且想在你自己的程序中发现性能问题,那么在 valgrind 下运行一次,然后用 -pg 编译它,然后在 gprof 下运行它。
    【解决方案2】:

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

    如果你真的想知道时间都去哪儿了,你可以试试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 倍的加速因子。当然,如果您真的想计算阶乘,还有其他方法可以加快此代码的速度,例如消​​除内部循环。

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 好的,如果我像这样更改代码: int main(void) { int fac=1;整数计数=10;诠释 k; for(k=1;k
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-07
      • 1970-01-01
      • 2013-03-15
      • 2013-07-21
      • 2014-05-27
      • 2015-05-27
      • 2016-03-20
      相关资源
      最近更新 更多