【问题标题】:measure time in a function in C在 C 中的函数中测量时间
【发布时间】:2023-03-31 15:17:01
【问题描述】:

我正在调试一个 C 应用程序,我想知道它在特定功能上花费了多少时间。

我可以更改源代码并添加更多代码来进行测量,但这对我来说似乎不合适。我宁愿用外部应用程序来做,而不是每次都重新编译。

我发现可以在 GDB 中设置断点,所以我想,一定可以通过简单的过程使用类似的工具来跟踪时间: - 设置断点 - 停止时,测量实际时间并运行该功能 - 离开功能时,再次测量时间 但是,我还没有找到如何在 gdb 中执行此操作的方法:(

有什么想法吗?谢谢

【问题讨论】:

    标签: c function time measure


    【解决方案1】:

    把它放到你的 ~/.gdbinit 中

    define timeme
        python import time
        python starttime=time.time()
        next
        python print("Previous takes: " + (str)(time.time()-starttime) + "s")
    end
    document timeme
        Measure executing time of next function
        Usage: timeme or ti
    end
    

    当您想测量下一个函数的时间时,键入timemeti

    【讨论】:

      【解决方案2】:

      我的 ~/.gdbinit 中有一个辅助函数:

      define timeme
      set $last=clock()
      n
      set $timing=clock() - $last
      if $timing>$arg0
      printf "***long***\n"
      end
      printf "%d cycles, %f seconds\n", $timing, (float)$timing / 1000000
      end
      

      您可能需要根据您的平台上的 CLOCKS_PER_SEC 实现来调整 1000000。

      使用是微不足道的;运行将执行下一步并提供时间信息的助手:

      Breakpoint 2, install_new_payload_from_meta (snmp_meta=0x7eee81c0, pkt=0x0, entry=0x7d4f4e58) at /home/sgillibr/savvi-dc-snmp/recipies.c:187
      (gdb) timeme 100000
      ***long***
      580000 cycles, 0.580000 seconds
      (gdb)
      

      显然分辨率可能不足以满足某些需求,尽管它确实非常有用。

      【讨论】:

      • 我在 C 文件中尝试了 sleep() 函数,它不起作用,结果总是 0。
      【解决方案3】:

      分析可能是您想要的。看看 prof 或 gprof。

      更新:使用“cc -Wall -ggdb -pg -g3 -O2 diskhash.c -o diskhash”编译(并运行程序)后,“gprof -p diskhash”给了我:

      Each sample counts as 0.01 seconds.
        %   cumulative   self              self     total           
       time   seconds   seconds    calls  ms/call  ms/call  name    
       32.60      0.41     0.41        1   410.75   646.18  create_hashtab
       31.80      0.81     0.40  5087692     0.00     0.00  hash_func
       27.83      1.16     0.35  2543846     0.00     0.00  find_hash
        2.78      1.20     0.04  2543846     0.00     0.00  chop_a_line
        1.59      1.22     0.02                             main
        0.40      1.22     0.01                             frame_dummy
        0.00      1.22     0.00        4     0.00     0.00  map_da_file
      

      【讨论】:

        【解决方案4】:

        gprof 是唯一可靠的——根据我的经验,只有在你静态链接 -pg 每个库的编译版本(包括 C 库)的情况下才有效。您可以尝试 使用 gcc 的 -profile 选项(它执行 -pg 所做的事情,并尝试在 -pg 库中子库)来执行此操作,但问题是,GNU libc 真的不喜欢静态链接,并且您的发行版可能不会提供您需要的每个库的 -pg 编译版本。

        我建议你试试cachegrind,这是valgrind 的操作模式,只需要所有的调试信息。这更容易获得。问题是,它有巨大的间接成本;如此之大,以至于它可能会使您的测试无效。预计至少会放缓 2 倍。

        你也可以试试perf——如果你能拿到一份副本的话。它非常聪明,但它适用于那些认为人们喜欢从头开始构建东西的内核黑客。我的运气好坏参半。 (请阅读http://web.eecs.utk.edu/~vweaver1/projects/perf-events/,它是关于底层 API 的,而不是实用程序,但仍然可以为您节省大量时间。)

        【讨论】:

          【解决方案5】:

          如果您使用的是 GCC,则需要编译选项“-pg”和应用程序 gprof

          【讨论】:

          • gprof 将显示函数被调用的次数,但不想显示次数。它只是说“没有时间积累”
          • 然后也许它被优化了或什么的。
          猜你喜欢
          • 1970-01-01
          • 2023-03-09
          • 1970-01-01
          • 1970-01-01
          • 2018-06-09
          • 1970-01-01
          • 2013-12-08
          相关资源
          最近更新 更多