如何在高度并发代码中提高.NET 4.0的垃圾回收器性能? [英] How can I improve garbage collector performance of .NET 4.0 in highly concurrent code?

查看:187
本文介绍了如何在高度并发代码中提高.NET 4.0的垃圾回收器性能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用.NET框架4中的任务并行库(特别是 Parallel.For Parallel.ForEach )然而,当我并行化一些任务,它们应该很容易并行化在双核机器上,我得到非常平庸的加速。

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:


  • 我应该尝试手动管理GC吗?

  • 我应该使用 Dispose 吗?

  • 我应该固定对象吗?

  • 我应该做其他不安全的代码技巧吗?

  • 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:

POSTSCRIPT:

问题不是GC运行得太频繁,它是GC阻止并行有效地并行运行代码。我也不认为分配更少的对象是一个可以接受的答案。这需要重写太多的代码来解决并行化的垃圾收集器。

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.

我已经找到了一个帮助整体表现的技巧()但是它没有帮助并发性能。换句话说, Parallel.For 在一个尴尬的并行任务上只比串行For循环快20%。

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:

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.

经过大量调查任务并行库没有正确地分布这些任务的核心工作,似乎是罪魁祸首是GC。显然GC似乎是一个瓶颈,因为它做了一些幕后的线程同步,我不明白。

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.

我需要知道的是什么确切地说,当执行大量分配时,GC会导致大量并发代码执行不当,以及我们如何解决之外的分配较少的对象。这种方法已经发生在我身上,并且需要大量重写大量代码。

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.

推荐答案

如果由于分配太多对象/ GC编译,GC运行太频繁,请尝试分配更少的对象: )

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).

不要尝试通过调用GC.Collect显式地管理GC,它很少支付( Rico Mariani这样说

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

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

这篇关于如何在高度并发代码中提高.NET 4.0的垃圾回收器性能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆