【问题标题】:gprof shows a simple signal handler takes a lot of CPUgprof 显示一个简单的信号处理程序占用大量 CPU
【发布时间】:2013-12-26 06:09:36
【问题描述】:

我使用 gprof 分析在 linux 上运行的程序,该程序使用 25ms 间隔计时器(由 timer_create() 创建)来更新全局变量。信号处理程序类似于 update_every_25ms(),它调用 profile_dummy() 来增加一个全局变量:

static void update_every_25ms(int sig_nr) { profile_dummy(); }
void profile_dummy(void) { global_var++; }

计时器是通过以下方式创建的:

timer_t timer;
struct itimerspec itimer;
timer_create(CLOCK_MONOTONIC, NULL, &timer)
itimer.it_interval.tv_sec = 0;
itimer.it_interval.tv_nsec = 25 * 1000 * 1000;
timer_settime(timer, 0, &itimer, NULL);

我的程序做了很多繁重的工作,但是 gprof 显示 update_every_25ms() 函数在 CPU 使用率为 100% 时花费了大部分时间,而这个函数本身每次调用大约需要 1.53 毫秒!

以下是间隔为25ms时的几组gprof输出:

%time  cumulative  self     calls  self    total    name
       seconds     seconds         ms/call ms/call
3.72   116.26      7.76     22963  0.34    0.34     profile_dummy

这里的 CPU 使用率为 60%。 为什么 profile_dummy() 每次调用需要 0.34 毫秒?

%time  cumulative  self     calls  self    total    name
       seconds     seconds         ms/call ms/call
9.38   38.87       38.87    25349  0.00    0.00     profile_dummy

这里的 CPU 使用率为 100%。 38.87s / 25349 = 1.53ms 但 gprof 输出 0.00,发生了什么?

%time  cumulative  self     calls  self    total    name
       seconds     seconds         ms/call ms/call
6.21   270.58      57.72 59105     0.00    0.00     profile_dummy

这里的 CPU 使用率为 90%。 57.72s / 59105 = 0.98ms 但 gprof 也输出 0.00。

这个是我把定时器间隔改成25s时的gprof输出:

%time  cumulative  self     calls  self    total    name
       seconds     seconds         ms/call ms/call
0.01   287.52      0.03  23        1.30    1.30     profile_dummy

函数只是增加了一个全局变量,为什么需要1.30ms?

感谢您的回复。

【问题讨论】:

  • 也许编辑问题以显示 timer_create() 调用与您使用的选项
  • 感谢 jwpat7。我添加了计时器代码。
  • 您是否有任何特殊原因没有引用 gprof 作为列标题的一部分打印的比例(usms 等...)?
  • @alk 抱歉,我无法将 gprof 输出复制出来,而是手动输入列标题和所有其他数据,所以我只输入了主要部分。
  • 嗯 .. - 我觉得知道我们谈论的是毫秒、微秒还是纳秒会很有趣。

标签: linux performance profiling signals gprof


【解决方案1】:

我只是在这里冒险猜测。

gprof 每 10ms 有一个信号中断,此时它对程序计数器 (PC) 进行采样。 例程的总自身时间是该例程中着陆的样本数。 由于它还计算对例程的调用,因此它可以获得每次调用的平均自我时间。

通常,当您的程序被阻塞时,例如 I/O、睡眠或多任务挂起,PC 是没有意义的,因此中断被挂起。 这就是为什么gprof 根本看不到 I/O。

但是,如果您有自己的定时器中断,那可能只会屏蔽分析器中断,而不是挂起它,导致它在您的定时器中断被解除后得到响应,这可能会将 PC 优先置于您的中断处理程序中。

但这只是猜测。

除非这纯粹是一个学术问题,否则有比gprof 更好的分析器。

【讨论】:

  • 非常感谢。有什么方法可以检查是不是你说的原因?如果我没有进展,我会尝试其他分析器。
  • @Dustin:有比gprof 更好的分析器,比如oprofileZoom,但就个人而言,我不仅仅对测量感兴趣。我想让代码尽可能快地运行,对我来说,the best profiler is no profiler.
猜你喜欢
  • 2016-05-17
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多