node_s / v8 flamegraph中使用perf_events的未知事件

时间:2015-01-08 14:19:08

标签: node.js performance profiling v8 perf

我尝试使用Brendan Gregg here所描述的Linux perf_events进行一些nodejs分析。

工作流程如下:

  1. 使用--perf-basic-prof运行节点> 0.11.13,创建/tmp/perf-(PID).map文件,其中写入了JavaScript符号映射。
  2. 使用perf record -F 99 -p `pgrep -n node` -g -- sleep 30
  3. 捕获堆栈
  4. 使用this存储库
  5. 中的stackcollapse-perf.pl脚本折叠堆栈
  6. 使用flamegraph.pl脚本
  7. 生成svg火焰图

    我得到以下结果(开头看起来非常好): enter image description here

    问题是有很多[unknown]元素,我认为应该是我的nodejs函数调用。我假设整个过程在第3点失败,其中perf数据应该使用由--perf-basic-prof执行的node / v8生成的映射来折叠。创建/tmp/perf-PID.map文件,并在节点执行期间向其写入一些映射。

    如何解决这个问题?

    我正在使用CentOS 6.5 x64,并且已经尝试使用节点0.11.13,0.11.14(预建和编译)但没有成功。

2 个答案:

答案 0 :(得分:15)

首先,“[unknown]”的含义是采样器无法找出函数的名称,因为它是系统或库函数。 如果是这样,那没关系 - 你不在乎,因为你在你的代码而不是系统代码中寻找负责时间的东西。

实际上,我建议这是其中一个XY questions。 即使您直接回答了您的要求,也可能没什么用处。 原因如下:

<强> 1。 CPU分析在I / O绑定程序中很少使用

火焰图左侧的两个塔正在进行I / O操作,因此它们可能比右侧的大堆需要更多的壁时间。 如果这个火焰图来自壁挂时间样本,而不是CPU时间样本,它可能看起来更像下面的第二张图,它告诉你实际上的时间:

enter image description here

右边一个多汁的大堆已经缩小了,所以它远没有那么重要。 另一方面,I / O塔非常宽。 如果你的代码中有任何一个宽橙色条纹代表了一个节省大量时间的机会,如果可以避免一些I / O.

<强> 2。无论程序是CPU还是I / O限制,加速机会都可以轻松隐藏火焰图

假设有一些函数Foo真的在做一些浪费的事情,如果你知道它,你可以解决。 假设在火焰图中,它是深红色。 假设它是从代码中的许多地方调用的,所以它并不是全部都收集在火焰图中的一个位置。 相反,它出现在黑色轮廓所示的多个小地方:

enter image description here

请注意,如果收集了所有这些矩形,您可以看到它占据了11%的时间,这意味着值得一看。 如果你可以减少一半的时间,你可以节省5.5%。 如果它实际上可以完全避免它,你可以节省11%的总体。 这些小矩形中的每一个都会缩小为零,然后将图形的其余部分拉到右边。

现在我会告诉你the method I use。我采用适量的随机堆栈样本,并检查每个样本可能加速的例程。 这对应于在火焰图中采样如下:

enter image description here

细长的垂直线表示20个随机时间堆栈样本。 如您所见,其中三个标有 X 。 这些是经过Foo的那些。 这是关于正确的数字,因为11%的20是2.2。

(困惑?好吧,这对你来说有点概率。如果你掷硬币20次,它有11%的机会上头,你会得到多少头?技术上它是二项式分布。最多你得到的可能数字是2,下一个最可能的数字是1和3.(如果你只得到1,你继续前进直到你得到2.)这是分布:)

enter image description here

(两次查看Foo所需的平均样本数为2 / 0.11 = 18.2个样本。)

看看这20个样本可能看起来有点令人生畏,因为它们的深度在20到50之间。 但是,您基本上可以忽略所有不属于您的代码。 只需检查它们您的代码即可。 你会精确地看到你是如何花时间的, 而且你会有一个非常粗略的衡量标准。 深筹码既是坏消息又是好消息 - 他们的意思是代码可能有很大的加速空间,他们会告诉你那些是什么。

你看到的任何你可以加速的东西,如果你在多个样本上看到它,将会给你一个健康的加速,保证。 您需要在多个样本上看到它的原因是,如果您只在一个样本上看到它,您只知道它的时间不为零。如果您在多个样本上看到它,您仍然不知道它需要多少时间,但您确实知道它不小。 Here are the statistics.

答案 1 :(得分:9)

一般来说,不同意主题专家是一个坏主意,但(最大的尊重)我们走了!

SO敦促答案做到以下几点:

&#34;请务必回答这个问题。提供详细信息并分享您的研究成果!&#34;

所以问题是,至少我对它的解释是,为什么在perf脚本输出中有[未知]帧(以及如何将这些[未知]帧转换为有意义的名称)? 这个问题可以关于如何提高我的系统性能?&#34;但在这种特殊情况下,我不会那么看。关于如何对perf记录数据进行后处理,这里存在一个真正的问题。

问题的答案是尽管前提条件设置正确:正确的节点版本,正确的参数用于生成函数名称(--perf-basic-prof), 生成的perf映射文件必须由root 拥有,以便脚本脚本生成预期的输出。

那就是它!

今天写了一些新的脚本我点击这个指引我这个问题。

以下是其他一些参考资料:

https://yunong.io/2015/11/23/generating-node-js-flame-graphs/

https://github.com/jrudolph/perf-map-agent/blob/d8bb58676d3d15eeaaf3ab3f201067e321c77560/bin/create-java-perf-map.sh#L22

[有时可以强制使用非根文件] http://www.spinics.net/lists/linux-perf-users/msg02588.html