.NET 4.0中的多线程和性能

Chr*_*ris 3 optimization multithreading asp.net-4.0

我一直在使用.NET 4.0中的并行库.最近,我为一些大型系统必须使用的一些不寻常的读/写操作开发了一个自定义ORM.这允许我用属性装饰一个对象,并反射出来确定它必须从数据库中提取哪些列,以及它在写入时输出的XML.

由于我设想这个包装器可以在许多项目中重用,我想尽可能多地挤出它.该库主要用于.NET Web应用程序.我正在使用一次性控制台应用程序来测试框架,以便查看我创建的类.

我现在已经了解了多线程所带来的开销.多线程使它运行得更慢.从阅读四周,好像这是直观的人谁已经做了很长一段时间,但它实际上是反直觉对我说:怎么能运行的方法30次在同一时间比运行它30次连续慢?

我认为我不会因为多个线程必须争夺相同的共享对象而导致问题(虽然我还不够好,但尚未确定),所以我认为减速来自于开销产生所有这些线程和运行时保持它们都是正确的.所以:

  • 虽然我这样做主要是作为一种学习练习,但这种悲观情绪呢?对于琐碎的非IO任务,多线程是否过度杀伤?我的主要目标是速度,而不是UI或任何东西的响应.
  • 在IIS中运行相同的多线程代码会导致它加速,因为线程池中已经创建了线程,而现在我正在使用一个控制台应用程序,我认为它是单线程的,直到我告诉它否则?我即将进行一些测试,但我认为有一些基础知识我不知道为什么它会是这样或那样的.我的控制台应用程序也在我的桌面上运行,有两个内核,而一个用于Web应用程序的服务器会有更多,所以我可能也必须使用它作为变量.

Sim*_*ens 8

Thread实际上并不是所有并发运行的.

在台式机上,我假设你有一个双核CPU,(最多可能是一个四核).这意味着只有2/4个线程可以同时运行.

如果你产生了30个线程,操作系统将不得不在这30个线程之间进行上下文切换以使它们全部运行.上下文切换非常昂贵,因此减速.

作为一个基本建议,如果您尝试优化计算,我的目标是每个CPU一个线程.除此之外你并没有真正做任何额外的工作,你只是在相同的CPU上交换线程.试着将您的计算机视为内部有限数量的工作人员,您不能同时完成比您可用的工作人员更多的工作.

.net 4.0并行任务库中的一些新功能允许您执行考虑线程数量可伸缩性的事情.例如,您可以创建一堆任务,并且任务并行库将在内部计算出您可用的CPU数量,并优化创建/使用的线程数,以免超载CPU,因此您可以创建30个任务,但是在双核机器上,TP库仍然只会创建2个线程,并排队.显然,当你在更大的机器上运行它时,这将非常好地扩展.或者您可以使用类似的方法ThreadPool.QueueUserWorkItem(...)来排队一堆任务,并且池将自动管理用于执行这些任务的线程数.

是的,线程创建有很多开销,但是如果你使用.net线程池(或4.0中的并行任务库).net将管理你的线程创建,你可能会发现它创建的线程少于您创建的任务数.它将在可用线程内部交换您的任务.如果您确实想要控制实际线程的显式创建,则需要使用Thread类.

[有些cpu可以用线程做聪明的东西,每个CPU可以运行多个线程 - 看看超线程 - 但是看看你的任务管理器,如果你今天的台式机上有超过4-8个虚拟CPU,我会感到非常惊讶]