什么可能导致性能提升? GC中的时间,汇集

时间:2011-04-10 16:33:57

标签: c# .net performance garbage-collection pooling

我们的多线程应用程序执行冗长的计算循环。平均而言,完成一个完整周期大约需要29秒。在此期间,.NET性能计数器% time in GC的测量值为8.5%。它全部由Gen 2系列组成。

为了提高性能,我们为大型对象实现了一个池。我们达到了100%的娱乐率。现在整个周期平均只需20秒。 “GC中的%时间”显示在0.3 ... 0.5%之间。现在GC只进行了第0代收藏。

让我们假设,池是有效实现的,忽略了执行所需的额外时间。比我们的性能提升大约33%。这与前一个GC的8.5%有什么关系?

我有一些假设,我希望可以确认,调整和修改:

1)“GC中的时间”(如果我读得正确)确实测量了2个时间跨度的关系:

  • 2个GC周期和
  • 之间的时间
  • 用于上一个完整GC循环的时间,该值包含在第一个跨度中。

第二个时间跨度中未包含的内容是停止和重新启动阻塞GC的工作线程的开销。但是,如何能够达到总执行时间的20%呢?

2)经常阻塞GC的线程可能会引起踏板之间的争用?这只是一个想法。我无法通过VS并发分析器确认。

3)与此形成对比的是,可以确认未填充应用程序(每秒25.000)的页面未命中数(性能计数器:内存 - >页面错误/秒)明显高于具有应用程序的应用程序低GC率(每秒200次)。我可以想象,这也将带来巨大的进步。但有什么可以解释这种行为?是这样,因为频繁的分配会导致虚拟内存地址空间中使用更大的区域,因此难以保留在物理内存中?怎么可以衡量这一点来确认原因?

BTW:GCSettings.IsServerGC = false,.NET 4.0,64bit,运行在Win7,4GB,Intel i5上。 (抱歉这个大问题......;)

2 个答案:

答案 0 :(得分:3)

  

然后我们获得了性能提升   大约33%。怎么样   与之前的GC值有关   8.5%?

通过合并,您还节省了new所花费的时间,这可能相当可观,但我不会花时间尝试平衡这些数字。

为什么不继续寻找其他“瓶颈”,而不是“在口中寻找礼物马”呢?

当您删除一个性能问题时,您会让其他人占用更大比例的时间,因为分母较小。 因此,它们更容易找到,如果您知道如何查找它们

Here's an example, and a method. 你解决了一个大问题。 这使得下一个更大,按百分比,所以你清理那个。 冲洗并重复。 它可能需要花费很少的时间,你需要在它周围包裹一个临时外环,只是为了让它花费足够长的时间进行调查。 你继续这样做,逐步使程序花费的时间越来越少,直到你收到递减的回报。

这就是如何快速制作代码。

答案 1 :(得分:2)

预先分配对象可以提高并发性,线程不再需要进入全局锁,以保护垃圾收集堆以分配对象。锁被保持很短的时间,但很明显你分配了很多对象,所以线程不可能争夺锁。

“GC中的时间”性能计数器测量收集而不是执行常规代码所花费的CPU时间百分比。如果有很多第2代集合,你可以得到一个很大的数字,你分配对象的速度非常快,以至于后台收集无法跟上并且线程必须被阻止。拥有更多线程会使情况变得更糟,您可以分配更多。