本文介绍了我怎样才能提高.NET 4.0中高并发code垃圾收集器的性能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用任务并行库从.NET框架4(特别是的Parallel.For Parallel.ForEach ),但是我并行的一些任务,看起来像他们应该很容易并行双核机时获得极其平庸的速度提升。

在分析系统,它看起来像有很多线程同步的,因为垃圾收集器的事情。我做了很多对象的分配,所以我想知道我怎么能提高并发性,同时最大限度地减少我的code重写。

例如是否有一些技术可以在这种情况下是有用的:

  • 我应该尝试手动管理GC?
  • 我应该使用处置
  • 我应该钉住对象?
  • 我应该做其他不安全code花样?

后记:

这个问题是不是常常运行GC,它是并行运行被GC的prevents并发code效率。我也并不认为分配较少的对象是一个可以接受的答案。这需要重写太多code,以解决不良的并行垃圾收集器。

我已经找到了一个窍门这有助于整体性能(using gcServer ),但它并没有帮助的并发性能。换句话说的Parallel.For 比串行For循环更快的只有20%,在一个尴尬的并行任务。

后后记:

好了,让我进一步解释,我有一个相当大的和复杂的程序:一个优化跨preTER。它是速度不够快,但我想它的时候(内置到我的语言基本操作)给出的并行任务的规模以及更多内核的可用性能。我在评估过程中分配大量的小对象。全除preTER设计是基于所有值从一个单一的多晶型基础对象被衍生。这在单线程应用程序的伟大工程,但是当我们尝试应用任务并行库并行的评价没有任何优势。

大量的调查研究为什么任务并行库是不正确的工作分配在整个内核来执行这些任务后,看来罪魁祸首就是GC。显然,GC似乎作为一个瓶颈,因为它做一些幕后的线程同步的,我不明白。

我需要知道的是:究竟是什么GC这样做,可能会导致严重的并发code执行不好当它大量拨款,以及我们如何解决这之外只是分配较少的对象。这种做法已经发生给我,将需要大量的code的显著重写。

解决方案

如果GC因过多的对象被分配/ GC-ED运行过于频繁,尝试分配他们少:)

根据您的情况 - 尝试重用现有对象,创建一个对象池,使用不把这么多的内存pressure(或更大,以减少分配的对象的数量)轻的对象。

不要试图通过显式调用GC.Collect的管理气相色谱法,它很少不负有心人(的)

http://blogs.msdn.com/ricom /archive/2003/12/02/40780.aspx

I am using the task parallel library from .NET framework 4 (specifically Parallel.For and Parallel.ForEach) however I am getting extremely mediocre speed-ups when parallelizing some tasks which look like they should be easily parallelized on a dual-core machine.

In profiling the system, it looks like there is a lot of thread synchronization going on because of the garbage collector. I am doing a lot of allocation of objects, so I am wondering how I can improve the concurrency while minimizing a rewrite of my code.

For example are there some techniques that can be useful in this situation:

  • Should I try to manage the GC manually?
  • Should I be using Dispose?
  • Should I be pinning objects?
  • Should I be doing other unsafe code tricks?

POSTSCRIPT:

The problem is not the GC running too often, it is that the GC prevents concurrent code from being running in parallel efficiently. I also don't consider "allocate fewer objects" to be an acceptable answer. That requires rewriting too much code to work around a poorly parallelized garbage collector.

I already found one trick which helped overall performance (using gcServer) but it didn't help the concurrent performance. In other words Parallel.For was only 20% faster than a serial For loop, on an embarrassingly parallel task.

POST-POSTSCRIPT:

Okay, let me explain further, I have a rather big and complex program: an optimizing interpreter. It is fast enough, but I want its performance when given parallel tasks (primitive operations built into my language) to scale well as more cores are available. I allocate lots of small object during evaluations. The whole interpreter design is based on all values being derived from a single polymorphic base object. This works great in a single-threaded application, but when we try to apply the Task Parallel Library to parallel evaluations there is no advantage.

After a lot of investigation into why the Task Parallel Library was not properly distributing work across cores for these tasks, it seems the culprit is the GC. Apparently the GC seems to act as a bottle-neck because it does some behind the scene thread synchronization that I don't understand.

What I need to know is: what exactly is the GC doing that can cause heavily concurrent code to perform badly when it does lots of allocations, and how we can work around that other than just allocating fewer objects. That approach has already occurred to me, and would require a significant rewrite of a lot of code.

解决方案

If GC is running too often due to too many objects being allocated/GC-ed, try to allocate fewer of them :)

Depending on you scenario - try to reuse existing objects, create an object pool, use "lighter" objects that do not put so much memory pressure (or larger to reduce the number of objects allocated).

Do not try to "manage GC" by calling GC.Collect explicitly, it very rarely pays off (Rico Mariani says so)

or http://blogs.msdn.com/ricom/archive/2003/12/02/40780.aspx

这篇关于我怎样才能提高.NET 4.0中高并发code垃圾收集器的性能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 15:13