【发布时间】:2013-08-30 16:06:49
【问题描述】:
我正在运行 64 位 Windows Server 2008 R2 Enterprise 的服务器上测试一个程序,它有 4 个 Intel E7-4870 处理器,总共 40 个内核和 80 个可用线程(我可以在Windows 任务管理器)。
程序代码如下:
numlist is List 包含数百个数字,每个数字都是用于某些计算的参数
Parallel.ForEach(numlist, num =>
{
// do some calculation using parameter = num
});
问题是当我在服务器上运行这个程序时,只有一半的可用线程显示在 windows 任务管理器中使用(当然 CPU 使用率显示为 50%),其余 40 个完全未使用和闲置。
我还在另一台只有 2 个处理器和总共 24 个可用线程的服务器上测试了相同的程序,所有 24 个线程都将被完全使用,并且 CPU 使用率显示为 100%。
有什么方法可以让 40 核 CPU 服务器运行这个程序并充分利用其所有可用的 80 个线程(或接近 80 个线程)?仅使用 50% 的 CPU 资源时性能不够好。
这是我正在测试的完整程序代码:
namespace Test
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Press any key to start");
Console.ReadLine();
List<int> numlist = new List<int>();
for (int i = 0; i < 100; i++)
{
numlist.Add(i);
}
Parallel.ForEach(numlist, num =>
{
while (true)
{
num++;
}
});
}
}
}
在有 2 个 Intel X5690 处理器(总共 24 个线程可用)的服务器上运行时,所有 24 个线程都被使用,并且 CPU 使用率显示为 100%;
但是当我在有 80 个可用线程的 4 处理器服务器上运行它时,只使用了 40 个线程,CPU 使用率只有 50%。有没有与此相关的编译器设置?
【问题讨论】:
-
你确定你有超过 40 个号码吗?这里确实没有太多信息,很难找出问题所在。
-
是的,为了组成numlist,我把这段代码放在并行循环之前: List
numlist = new List (); for (int i = 0; i -
尝试在
ParalellOptions中使用MaxDegreeOfParallelism -
我试过了,MaxDegreeOfParallelism 没有帮助。我什至创建了两个Task对象,每个都包含一个parallel.foreach循环,并在程序内部同时启动两个任务。 CPU 使用率仍然是 50%,并且只使用了一半的线程。
-
澄清一下,我发现这个问题的原因是,我正在写一个大型的windows服务系统,并行循环内部有复杂的业务逻辑。我在不同的服务器上测试了该服务并发现了这个问题。于是就写了上面的小测试。从测试结果来看,这个问题似乎与并行循环内部的内容无关,只是c#编译器自己确定“40核80线程对于单个exe进程来说太多了”。
标签: c# multithreading threadpool cpu parallel.foreach