我正在运行使用.NET 2.0构建的.NET远程处理应用程序。它是一个控制台应用程序,虽然我删除了Main上的[STAThread]。
我正在使用的TCP频道在后台使用ThreadPool。
据我所知,当在双核盒上运行时,在负载下,应用程序从不使用超过50%的CPU(尽管我在四核处看到它的70%或更多)。
远程应用程序或ThreadPools的多核方面是否有任何限制?
是否需要更改某些内容以便在多个内核上运行多线程应用程序?
由于
答案 0 :(得分:10)
应该没有。
有几个原因导致您看到此行为:
您的主题是IO绑定。
在这种情况下,您将看不到很多并行性,因为所有内容都将在磁盘上等待。单个磁盘本质上是顺序的。
您的锁定粒度太小
您的应用可能花费大部分时间来获取锁定,而不是执行您的应用逻辑。这可以大大减慢速度。
您的锁定粒度太大
如果你的锁定不够精确,你的其他线程可能会花很多时间等待。
您有很多锁争用
你的线程可能都在试图同时锁定相同的资源,使它们本身是连续的。
您可能无法正确分区线程。
您可能在多个线程上运行了错误的操作。例如,如果每个连接使用一个线程,则可能无法利用在该线程上运行的任务中的可用并行性。尝试将这些任务拆分为可以并行运行的块。
您的流程可能没有很多可用的并行性
你可能只是在做那些无法并行完成的事情。
我会尝试调查每一个,看看原因是什么。
答案 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文档,了解各种数字对于亲和力的含义。