我正在尝试通过使用来加快计算时间Parallel.For
。for
我有一个 8 核的 Intel Core i7 Q840 CPU,但与顺序循环相比,我只能获得 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 秒,性能比仅为 4.0。
在任务管理器中,我可以看到顺序计算时 CPU 使用率为 10-11%,而并行计算时仅为 70%。我试图明确设置
ParallelOptions.MaxDegreesOfParallelism = Environment.ProcessorCount
但无济于事。我不清楚为什么不将所有 CPU 功率分配给并行计算?
我注意到之前有人在 SO 上提出过类似的问题,结果更令人失望。但是,该问题还涉及第三方库中较差的并行化。我主要关心的是核心库中基本操作的并行化。
更新
在一些评论中向我指出,我使用的 CPU 只有 4 个物理内核,如果启用了超线程,则系统可以看到 8 个内核。为此,我禁用了超线程并重新进行了基准测试。
禁用超线程后,我的计算现在更快了,无论是并行循环还是(我认为是)顺序for
循环。循环期间的 CPU 利用率for
高达约。Parallel.For
循环期间 45% (!!!) 和 100% 。
循环的计算时间为15.6 秒(比启用for
超线程时快两倍多)和 6.2 秒(比启用超线程时好 25% )。性能比现在只有2.5,运行在 4 个真正的核心上。Parallel.For
Parallel.For
因此,尽管禁用了超线程,但性能比仍然大大低于预期。另一方面,for
循环期间 CPU 利用率如此之高是不是很有趣?在这个循环中是否还会发生某种内部并行化?