多线程应用程序是否绑定到单个核心?

时间:2009-06-30 01:10:38

标签: c# performance multithreading

我正在运行使用.NET 2.0构建的.NET远程处理应用程序。它是一个控制台应用程序,虽然我删除了Main上的[STAThread]。

我正在使用的TCP频道在后台使用ThreadPool。

据我所知,当在双核盒上运行时,在负载下,应用程序从不使用超过50%的CPU(尽管我在四核处看到它的70%或更多)。

远程应用程序或ThreadPools的多核方面是否有任何限制?

是否需要更改某些内容以便在多个内核上运行多线程应用程序?

由于

3 个答案:

答案 0 :(得分:10)

应该没有。

有几个原因导致您看到此行为:

  1. 您的主题是IO绑定。

    在这种情况下,您将看不到很多并行性,因为所有内容都将在磁盘上等待。单个磁盘本质上是顺序的。

  2. 您的锁定粒度太小

    您的应用可能花费大部分时间来获取锁定,而不是执行您的应用逻辑。这可以大大减慢速度。

  3. 您的锁定粒度太大

    如果你的锁定不够精确,你的其他线程可能会花很多时间等待。

  4. 您有很多锁争用

    你的线程可能都在试图同时锁定相同的资源,使它们本身是连续的。

  5. 您可能无法正确分区线程。

    您可能在多个线程上运行了错误的操作。例如,如果每个连接使用一个线程,则可能无法利用在该线程上运行的任务中的可用并行性。尝试将这些任务拆分为可以并行运行的块。

  6. 您的流程可能没有很多可用的并行性

    你可能只是在做那些无法并行完成的事情。

  7. 我会尝试调查每一个,看看原因是什么。

答案 1 :(得分:6)

多线程应用程序将使用您的所有核心。

我怀疑你的行为是由于这个陈述:

  

我正在使用的TCP频道在后台使用ThreadPool。

TCP以及大多数套接字/文件/等代码往往使用非常少的CPU。它花费大部分时间等待,因此程序的CPU使用率可能永远不会飙升。尝试使用大量计算的线程池,你会看到你的处理器峰值接近100%的CPU使用率。

答案 2 :(得分:4)

多线程应用程序不需要绑定到单个核心。您可以使用ProcessThread.ProcessorAffinity检查线程的关联性(它操作的核心数)。我不确定默认行为是什么,但如果需要,可以以编程方式更改它。

以下是如何执行此操作的示例(taken directly from TechRepublic

Console.WriteLine("Current ProcessorAffinity: {0}", 
                  Process.GetCurrentProcess().ProcessorAffinity);

Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)2;

Console.WriteLine("Current ProcessorAffinity: {0}", 
                  Process.GetCurrentProcess().ProcessorAffinity);

输出:

  

Current ProcessorAffinity: 3
  Current ProcessorAffinity: 2

上面的代码首先显示该进程在两个核心上运行。然后它变为仅使用第二个核心,并显示它现在只使用第二个核心。您可以阅读ProcessorAffinity上的.NET文档,了解各种数字对于亲和力的含义。