在分析时,我们知道“自用时间”是指忽略调用的函数的方法所花费的时间,而“总时间”是指该方法及其子函数被调用的总时间。
我有一个简单的函数,我只对数组进行计算而不调用内部的任何其他函数。但是,在分析时,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/