15

我一直致力于优化分析社交图数据的代码(在https://blog.golang.org/profiling-go-programs的帮助下),并且我已经成功地修改了很多慢代码。

所有数据首先从db加载到内存中,从那里分析数据出现CPU绑定(最大内存消耗<10MB,CPU1@100%)

但是现在我程序的大部分时间似乎都在 runtime.osyield 和 runtime.usleep 中。有什么办法可以防止呢?

我设置了 GOMAXPROCS=1 并且代码不会产生任何 goroutines(除了 golang 库可能调用的)。

这是我 pprof 的前 10 名输出

(pprof) top10
62550ms of 72360ms total (86.44%)
Dropped 208 nodes (cum <= 361.80ms)
Showing top 10 nodes out of 77 (cum >= 1040ms)
      flat  flat%   sum%        cum   cum%
   20760ms 28.69% 28.69%    20850ms 28.81%  runtime.osyield
   14070ms 19.44% 48.13%    14080ms 19.46%  runtime.usleep
   11740ms 16.22% 64.36%    23100ms 31.92%  _/C_/code/sc_proto/cloudgraph.(*Graph).LeafProb
    6170ms  8.53% 72.89%     6170ms  8.53%  runtime.memmove
    4740ms  6.55% 79.44%    10660ms 14.73%  runtime.typedslicecopy
    2040ms  2.82% 82.26%     2040ms  2.82%  _/C_/code/sc_proto.mAvg
     890ms  1.23% 83.49%     1590ms  2.20%  runtime.scanobject
     770ms  1.06% 84.55%     1420ms  1.96%  runtime.mallocgc
     760ms  1.05% 85.60%      760ms  1.05%  runtime.heapBitsForObject
     610ms  0.84% 86.44%     1040ms  1.44%  _/C_/code/sc_proto/cloudgraph.(*Node).DeepestChildren
(pprof)

_ /C_/code/sc_proto/* 函数是我的代码。

以及来自网络的输出: 网络输出

(更好的是,SVG 版本的图在这里:https ://goo.gl/Tyc6X4 )

4

1 回答 1

10

自己找到了答案,所以我在这里为遇到类似问题的其他人发布此问题。特别感谢@JimB 让我走上了正确的道路。

从图中可以看出,通向 osyield 和 usleep 的路径是垃圾回收例程。这个程序使用了一个链表,它生成了很多指针,这为 gc 创建了很多工作,在清理我的混乱时偶尔会阻止我的代码执行。

最终,这个问题的解决方案来自https://software.intel.com/en-us/blogs/2014/05/10/debugging-performance-issues-in-go-programs(顺便说一句,这是一个很棒的资源)。我按照那里有关内存分析器的说明进行操作;并且用切片替换指针集合的建议清除了我的垃圾收集问题,我的代码现在更快了

于 2016-02-02T17:57:48.817 回答