【发布时间】:2014-02-01 01:28:06
【问题描述】:
我正在使用 C++ 为 OSX 上的第三方主机应用程序开发插件。它被编译为 .dylib。我希望在我的插件在宿主应用程序中运行时对其进行概要分析。
不幸的是,主机调用插件代码的速度取决于插件的(最后)执行时间。这意味着该过程的总时间相对于实时可能会有很大差异。因此,使用采样分析器,插件中的“花费时间”并没有真正基于任何有用的东西,因为它只是与属于该过程的堆栈帧进行比较。如果我改进了插件的性能,那么宿主执行插件的模式会相应地改变,并且很难衡量插件内部的改进。
我可以使用 Instruments,但据我所知,我只能获得相对于进程 CPU 时间的相对时间。
我已经使用 dtrace 来获取主机进程的用户堆栈直方图:
#!/usr/sbin/dtrace -s
#pragma ustackframes 100
#pragma D option quiet
/* $1 is pid */
/* $2 is sample rate in Hz (e.g. 100) */
/* $3 is duration (e.g. '20s') */
profile-$2
/pid == $1 && arg1/
{
@[ustack()] = count();
}
tick-$3
{
exit(0);
}
这可行,但它仍然只提供相对于进程时间的样本,因为谓词只匹配然后进程在用户空间中。即使在进程的内核调用期间删除&& arg1 条件以触发它也无济于事。
我真正想知道的是有多少profile-n 样本导致进程根本没有运行。然后我可以将插件中的数字与样本总数进行比较,并为我的插件函数获取 absolute 样本值。这让我想知道 - 假设请求的 profile-n 采样率得到满足是否安全?我可以简单地花费时间*采样率并使用它来计算“关闭过程”时间吗?我假设在 1500Hz 时,它会丢弃样本并以其他未知的速率运行,但如果我可以确定它以 1500Hz 的频率进行采样,那么我可以从中计算出“关闭进程”时间。
或者,是否有一种已知的方法可以使用 dtrace 进行 wall-clock 分析?
【问题讨论】:
-
我会问Brendan Gregg。他是 DTrace 方面的专家,他展示了如何进行他所谓的堆栈分析,类似于 Random Pausing,除了他展示了如何“在 CPU 上”和“在 CPU 外”进行,但不是挂钟时间。如果有人知道怎么做,他应该知道。我会在如何分析堆栈样本方面与他不同。他进入了火焰图,我认为这很吸引人。恕我直言,应该仔细检查几个样本中的每一个,就好像它指向一个错误一样。
标签: c++ macos profiling stack-trace dtrace