gpt4 book ai didi

c# - Parallel.For 令人失望的性能

转载 作者:IT王子 更新时间:2023-10-29 04:53:37 37 4
gpt4 key购买 nike

我试图通过使用 Parallel.For 来加快我的计算时间。我有一个 8 核的 Intel Core i7 Q840 CPU,但与顺序 for 循环相比,我只能获得 4 的性能比。这是否与 Parallel.For 一样好,还是可以微调方法调用以提高性能?

这是我的测试代码,顺序:

var loops = 200;
var perloop = 10000000;

var sum = 0.0;
for (var k = 0; k < loops; ++k)
{
var sumk = 0.0;
for (var i = 0; i < perloop; ++i) sumk += (1.0 / i) * i;
sum += sumk;
}

和并行:

sum = 0.0;
Parallel.For(0, loops,
k =>
{
var sumk = 0.0;
for (var i = 0; i < perloop; ++i) sumk += (1.0 / i) * i;
sum += sumk;
});

我正在并行化的循环涉及使用“全局”定义的变量 sum 进行计算,但这应该只占并行化循环内总时间的一小部分。

在发布版本(“优化代码”标志集)中,顺序 for 循环在我的计算机上需要 33.7 秒,而 Parallel.For 循环需要 8.4 s,性能比仅为4.0。

在任务管理器中,我可以看到顺序计算时CPU利用率为10-11%,而并行计算时只有70%。我试图明确设置

ParallelOptions.MaxDegreesOfParallelism = Environment.ProcessorCount

但无济于事。我不清楚为什么不是所有 CPU 能力都分配给并行计算?

Sequential vs. parallel CPU utilization

我注意到有人在 SO before 上提出了类似的问题,结果更令人失望。但是,该问题还涉及第三方库中较差的并行化。我主要关心的是核心库中基本操作的并行化。

更新

有人在一些评论中向我指出,我使用的 CPU 只有 4 个物理内核,如果启用了超线程,这对系统来说是 8 个内核。为此,我禁用了超线程并重新进行了基准测试。

在超线程禁用的情况下,我的计算现在更快,无论是并行还是(我认为是)顺序环形。 for 循环期间的 CPU 使用率高达大约。 45% (!!!) 和 100% 在 Parallel.For 循环中。

for 循环的计算时间为 15.6 秒(比超线程启用快两倍),Parallel.For (比启用超线程时好 25%)。 Parallel.For 的性能比现在仅为 2.5,在 4 个真实内核上运行。

因此,尽管禁用了超线程,但性能比仍然大大低于预期。另一方面,有趣的是 for 循环期间 CPU 利用率如此之高?这个循环中是否也存在某种内部并行化?

最佳答案

即使您没有使用锁,使用全局变量也会带来严重的同步问题。当您为变量赋值时,每个内核都必须访问系统内存中的相同位置,或者等待另一个内核完成后再访问它。您可以通过使用打火机来避免没有锁的损坏 Interlocked.Add方法在操作系统级别以原子方式将值添加到总和,但您仍然会由于争用而延迟。

执行此操作的正确方法是更新线程局部变量以创建部分和,并在最后将它们全部添加到单个全局和中。 Parallel.For有一个重载可以做到这一点。 MSDN 甚至在 How To: Write a Parallel.For Loop that has Thread Local Variables 上有一个使用求和的示例

        int[] nums = Enumerable.Range(0, 1000000).ToArray();
long total = 0;

// Use type parameter to make subtotal a long, not an int
Parallel.For<long>(0, nums.Length, () => 0, (j, loop, subtotal) =>
{
subtotal += nums[j];
return subtotal;
},
(x) => Interlocked.Add(ref total, x)
);

每个线程更新自己的 subtotal 值,并在完成时使用 Interlocked.Add 更新全局 total

关于c# - Parallel.For 令人失望的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10846550/

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