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

CMi*_*Guy 7 c# cpu multithreading threadpool parallel.foreach

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

程序代码如下:

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

Parallel.ForEach(numlist, num =>
                 {
                    // do some calculation using parameter = num             
                 });
Run Code Online (Sandbox Code Playgroud)

问题是当我在服务器上运行这个程序时,只有一半的可用线程显示在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++;
                                 }
                             });

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当它在具有2个Intel X5690处理器的服务器上运行时(共有24个线程可用),所有24个线程都被使用,CPU使用率显示为100%;

但是当我在具有80个可用线程的4处理器服务器上运行它时,只使用了40个线程,CPU使用率仅为50%.是否有与此相关的编译器设置?

Ree*_*sey 9

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

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

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

在最佳情况下,超线程往往会导致整体性能提高约30%.为此,您通常需要不同的CPU指令来推动核心上的每个线程,因此核心可以正常执行工作.在许多超线程"CPU线程"中并行运行相同的计算时,您通常会发现每个核心运行一个进程没有优势.

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