如何通过Parallel.ForEach实现最大的并行度并利用最大的CPU? [英] How can I achieve maximum parallelism and utilize maximum CPU with Parallel.ForEach?

查看:468
本文介绍了如何通过Parallel.ForEach实现最大的并行度并利用最大的CPU?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个C#函数 A(arg1,arg2),需要多次调用。为了做到这一点,我使用了并行编程。

There is a C# function A(arg1, arg2) which needs to be called lots of times. To do this fastest, I am using parallel programming.

以下面的代码为例:

long totalCalls = 2000000;
int threads = Environment.ProcessorCount;

ParallelOptions options = new ParallelOptions(); 
options.MaxDegreeOfParallelism = threads;

Parallel.ForEach(Enumerable.Range(1, threads), options, range =>
{
    for (int i = 0; i < total / threads; i++)
    {
        // init arg1 and arg2
        var value = A(arg1, agr2);
        // do something with value
    }
});

现在的问题是,这并没有随着内核数量的增加而扩大;例如在8核上使用80%的CPU,在16核上使用40-50%的CPU。我想最大程度地使用CPU。

Now the issue is that this is not scaling up with an increase in number of cores; e.g. on 8 cores it is using 80% of CPU and on 16 cores it is using 40-50% of CPU. I want to use the CPU to maximum extent.

您可以假设 A(arg1,arg2)内部包含一个计算复杂,但没有任何IO或网络绑定操作,也没有线程锁定。还有什么其他可能性可以找出代码的哪一部分不能使其以100%并行的方式执行?

You may assume A(arg1, arg2) internally contains a complex calculation, but it doesn't have any IO or network-bound operations, and also there is no thread locking. What are other possibilities to find out which part of the code is making it not perform in a 100% parallel manner?

我还尝试提高并行度,例如

I also tried increasing the degree of parallelism, e.g.

int threads = Environment.ProcessorCount * 2;
// AND
int threads = Environment.ProcessorCount * 4;
// etc.

但这没有帮助。

更新1 -如果我通过将一个简单的函数替换 A()来运行相同的代码,质数,那么它正在利用100个CPU并很好地扩展。因此,这证明其他代码是正确的。现在,问题可能在原始函数 A()中。我需要一种方法来检测导致某种排序的问题。

Update 1 - if I run the same code by replacing A() with a simple function which is calculating prime number then it is utilizing 100 CPU and scaling up well. So this proves that other piece of code is correct. Now issue could be within the original function A(). I need a way to detect that issue which is causing some sort of sequencing.

推荐答案

您已确定<$中的代码c $ c> A 是问题。

有一个非常普遍的问题:垃圾回收。在 app.config 中配置应用程序以使用并发服务器GC。 Workstation GC倾向于序列化执行。

There is one very common problem: Garbage collection. Configure your application in app.config to use the concurrent server GC. The Workstation GC tends to serialize execution. The effect is severe.

如果不是这个问题,请暂停调试器几次,然后查看 Debug->。并行堆栈窗口。在那里,您可以看到线程在做什么。寻找共同的资源和竞争。例如,如果您发现很多线程在等待锁,这就是问题所在。

If this is not the problem pause the debugger a few times and look at the Debug -> Parallel Stacks window. There, you can see what your threads are doing. Look for common resources and contention. For example if you find many thread waiting for a lock that's your problem.

另一种不错的调试技术是注释掉代码。一旦可伸缩性限制消失,您就知道是由什么代码引起的。

Another nice debugging technique is commenting out code. Once the scalability limit disappears you know what code caused it.

这篇关于如何通过Parallel.ForEach实现最大的并行度并利用最大的CPU?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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