我刚刚开始使用线程,很快我就遇到了很多线程太多的常见问题? 在做了一些研究后,我更加困惑。
任务
我有16个核心和一个生成1000个对象的应用程序,尽管建筑参数一致。根据msdn文档和Maximum number of threads,创建1000个线程通常会产生巨大的开销,从而破坏多线程的性能优势。此外,我必须保持在3.5 NET 32位限制(Maximum number of threads in a .NET app?)。
问题1
有这样一个单方面的任务,是否有可能创建比计算机上的核心更多的线程? .NET优化了什么吗?我应该使用的最大线程数是多少?
问题2
是否有一个简单的美丽解决方案,除了用限制资源排队?像信号量一样,我创建所有1000个线程但是立即停用线程以便不分配默认线程堆栈?
答案 0 :(得分:5)
是的,您可以(并且可能应该)创建比核心更多的线程,因为操作系统调度程序将中断以交换活动线程,即使没有其他任何东西在等待那个核心。但是,您也不想创建1000个单独的线程。相反,创建一些线程并在它们之间划分工作,以便每个线程处理完整作业中的多个项目。
我发现一个好的经验法则是每个逻辑核心使用两个线程(这会计算超线程核心...如果你有一个8核cpu,具有16个逻辑核心的超线程,请创建32个线程)。这个想法是你希望尽可能少的调度程序中断/上下文交换,但同时保持所有内核忙于主要完成你的任务。给定调度程序中断将仍然发生,即使逻辑核心上没有其他活动,对该核心具有两个活动线程意味着调度程序可能只是放入空闲线程你的计划。即使其他东西对于该核心是活跃的,它现在仍然可能是您选择执行的线程。高于此值可以鼓励更多的上下文切换,并且会损害性能。
简短版本是每个核心的第二个线程的成本很低(因为上下文切换仍然发生),但是回报可能很高(整个调度程序阻止cpu在你的应用程序上工作而不是其他东西)。当您为每个核心添加更多线程时,您开始增加成本并降低潜在收益。
但那只是我的经历。它的非常概括,并且不仅仅是一个起点。您确实需要个人资料您的应用如何使用不同的广告代码行事,以了解如何调整此广告以获得最佳效果。
最后,在.Net世界中,值得一提的是ThreadPool
和async Tasks。这不是进入这些主题的完整教程的最佳位置,但阅读它们非常值得您花时间。
答案 1 :(得分:3)
是否可以在计算机上创建比核心更多的线程?
是的,这是可能的。
.NET优化了什么吗? 我应该使用的最大线程数是多少?
实际上,你不应该关心99.99%的情况下的线程数,因为你......不得在99.99%的情况下手动创建线程。如果必须保留在.NET 3.5中,请改用ThreadPool
。如果您的版本是4.0或更高版本,请使用tasks。
是否有一个简单的美丽解决方案,除了用限制资源排队?
事实上,没有。你不能跳过物理上可用的资源,这是瓶颈。
答案 2 :(得分:1)
基本上,当您获得更多线程时,新线程的性能百分比越来越少。 10个线程的运行速度比1个线程快10倍。此外,当你获得更多的线程运行而不是核心时,你不会从中获得任何有意义的。
经验法则是使用线程来执行高性能代码,让它在后台而不是在UI线程上运行,这样就可以避免阻止UI响应。如果您想优化已经非UI块的代码,那么您可以查看目标机器上的核心数量,并创建更多线程以帮助重型算法(如果有意义的话)。请记住,调试起来要困难得多,而且维护和编写多线程代码要困难得多。
因此,只有在实验和学习时才这样做,否则只有当你真的需要将一些额外的力量压缩到应用程序中时才会这样做。
答案1:是的,可以创建比核心更多的线程,但它几乎没有意义。
回答2:不要创建1000个线程来创建1000个对象!那不漂亮