gpt4 book ai didi

c# - 如何通过 Parallel.ForEach 实现最大并行度并利用最大 CPU?

转载 作者:太空狗 更新时间:2023-10-29 19:38:32 26 4
gpt4 key购买 nike

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

以下面的代码为例:

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。

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

我也试过增加并行度,例如

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

但这并没有帮助。

更新 1 - 如果我通过将 A() 替换为计算素数的简单函数来运行相同的代码,那么它会占用 100 个 CPU 并且可以很好地扩展.所以这证明另一段代码是正确的。现在问题可能出在原始函数 A() 中。我需要一种方法来检测导致某种排序的问题。

最佳答案

您已确定A 中的代码是问题所在。

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

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

另一个很好的调试技术是注释掉代码。一旦可伸缩性限制消失,您就会知道是什么代码导致了它。

关于c# - 如何通过 Parallel.ForEach 实现最大并行度并利用最大 CPU?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38243432/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com