CPU中使用的线程数不能超过可用线程总数的一半

本文关键字:线程 一半 CPU 不能 | 更新日期: 2023-09-27 18:29:25

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

程序代码如下:

numlist是包含数百个数字的列表,每个数字都是要在某些计算中使用的参数

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

CPU中使用的线程数不能超过可用线程总数的一半

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

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

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

在最佳情况下,超线程往往会使总体性能提高30%左右。为了实现这一点,通常需要不同的CPU指令来推动内核上的每个线程,这样内核才能正确地执行工作。当在多个超线程"CPU线程"上并行运行相同的计算时,与每个核心运行一个进程相比,您通常看不到任何优势。

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