7

我正在运行 64 位 Windows Server 2008 R2 Enterprise 的服务器上测试一个程序,它有 4 个 Intel E7-4870 处理器,总共 40 个内核和 80 个可用线程(我可以在 Windows 任务管理器中看到 80 个 CPU 使用率图)。

程序代码如下:

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%。是否有任何与此相关的编译器设置?

4

1 回答 1

9

根据工作类型,超线程并不总是有帮助。对于许多类型的纯数学运算,每个内核只能有效处理一个工作项,而不是处理器“线程数”建议的 2 个。

超线程实际上并不是独立的内核,因此在它们上运行的指令并不总能带来收益。这在这里讨论

根据集群配置,最重要的是,根据集群上运行的应用程序的性质,性能增益可能会有所不同,甚至是负面的。下一步是使用性能工具来了解哪些领域有助于提高性能以及哪些领域会导致性能下降。

在最佳情况下,超线程往往会导致整体性能提高 30% 左右。为此,您通常需要通过内核上的每个线程推送不同的 CPU 指令,以便内核可以正常执行工作。当跨多个超线程“CPU 线程”并行运行相同的计算时,与每个内核运行一个进程相比,您通常不会看到任何优势。

这也可能是因为您使用的是托管代码,该代码将仅限于处理器组 0,因为 CLR 不使用 Windows 2008 R2 中的新 NUMA 指令。因此,如果您的系统设置为处理器组 0 为 40 个处理器,而其他 40 个处理器被拆分为处理器组 1,则您可能会用此进程使整个第一个处理器组饱和。有关详细信息,请参阅如何开始使用多核:您可以使用的并行处理

于 2013-08-27T19:10:42.823 回答