c++ - 概要分析:一行简单代码的 self 时间与总时间

标签 c++ c multithreading profiling profiler

在分析时,我们知道“自用时间”是指忽略调用的函数的方法所花费的时间,而“总时间”是指该方法及其子函数被调用的总时间。

我有一个简单的函数,我只对数组进行计算而不调用内部的任何其他函数。但是,在分析时,self 和 total 的时间对于函数本身以及函数的每一行都是完全不同的。这是来自 Zoom Profiler 的示例分析线,使用 32 个线程运行。

for循环中行的时序

Total        Self         Code
29.4 sec     16.9 sec     id=*(pid); 

让我感到困惑的是,根据第一段,它应该意味着如果一行代码不调用任何方法,则自身时间和总花费时间应该相同。 对正在发生的事情有什么想法吗?

最佳答案

我不会太担心这个。

剖析器显示的统计数据,即使是优秀的剖析器,也必须“持保留态度”。 这些统计数据表明,在某些包含该行代码的堆栈示例中,它不是堆栈中的最后一行代码,这很难相信。 更容易相信探查器是错误的。 如今,由于处理器拥有超前运行的管道,这可能会让人非常困惑。

无论如何,如果您进行概要分析的原因是为了寻找加速,则很难看出如何加速该特定代码行。 您正在寻找您可以加速的东西,而不是您不能的东西。

顺便说一句,我建议不要看秒或毫秒或任何绝对时间测量,而是看小数时间 - 时间除以总时间。 真正的加速往往占更大的比例,从 5% 到 99%。 此外,不要打扰自己的时间 - 包含时间包括它,如果程序有任何重要的大小,那么堆栈样本会变深,堆栈样本上的非终端行(即函数调用)是一个丰富的狩猎加速的基础。 最后,不需要测量精度,因此不需要大量的样本。

这就是为什么很多人使用 this technique 的原因.


编辑:FWIW,这就是我的意思。这里有 5 个随机时间堆栈示例:

---------------------------
... some calls above
... exp(4.02) ...
... some calls below
---------------------------
... some calls above
... exp(0.35) ...
... some calls below
---------------------------
... some calls above
... push_back(...) ...
...
... new ...
...
---------------------------
...
... myArray[...]
...
---------------------------
... some calls above
... exp(0.35) ...
... some calls below
---------------------------

其中三个在堆栈上、您的代码中或您可以编辑的代码中调用了 exp,很可能来自代码中的不同位置。 这意味着您花费大约 60% 的时间调用 exp。 你不能加速那个函数,但你能少调用它吗?

现在请注意,第二个和第五个示例使用相同的数字参数调用 exp。 (这是任何分析器都无法告诉你的。) 那是什么意思? 这意味着大约 40% 的时间是在带有重复参数的 exp 调用中, 您可以通过记住先前的值或内存 exp 来避免这种情况。

如果您采集样本直到您看到某种您可以采取措施的模式,并且您看到它两次或更多次,您就获得了健康的加速。 达到该点所需的样本越少,加速越大。 然后你可以重复整个过程,直到你不能再做为止。 这是获得难以匹敌的速度的可靠方式。

关于c++ - 概要分析:一行简单代码的 self 时间与总时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33949467/

相关文章:

c++ - 将变量数据发送到其他类时出现问题

c - 在C中设置TCP重传超时

C 链表 - 指针值变化

c++ - 在 matlab 中编写一个非常基本的 mex 函数

C++ Plist 解析器

从 backtrace_symbols 接收到的 c++ 符号不显示 g++ 中的函数

c - 打印链表中的节点时无限循环

multithreading - 在长时间任务期间保持应用程序响应

java - HashMap在迭代过程中插入

java - 使用 Quartz 工作线程拆分 log4j 输出