我可以同时运行多少个线程?
Posted
技术标签:
【中文标题】我可以同时运行多少个线程?【英文标题】:How many threads can I run concurrently? 【发布时间】:2011-01-28 12:38:05 【问题描述】:another of my questions 的评论说我只能同时运行“这么多”线程,这是我在其他地方看到的概念。
作为线程新手,我如何确定要使用的最大线程数?或者这是一个“一根绳子有多长”的问题?这取决于什么?硬件配置还是什么?
(MS Visual Studio 中的 .Net 3.5 中的 VB,如果重要的话)
更新:是否有人知道任何可以建议多个线程(或任务)的软件工具,还是我应该自己编写代码,不断尝试不同的数字,直到吞吐量下降?
[更新] 差不多七年后,我们现在有了a software recommendations site,所以如果有工具可以帮助解决这个问题,我asked。
【问题讨论】:
+1 好问题。他们每个人都进行一次 SOAP 调用来传输 soem 数据并等待它返回 当然,除了“返回”是异步的,所以他们并不是真的在等待。只要通过 HTTP 发送 SOAP 请求(函数调用),其他线程就可以运行 【参考方案1】:这取决于硬件,因为您(可能)不是使用理论计算机而是物理硬件,因此您的资源有限。
阅读:Does Windows have a limit of 2000 threads per process?
此外,即使您可以运行 5000 多个线程(取决于您的硬件),它的运行速度也可能比 10 线程等效程序慢得多。我想你应该看看thread pooling。
【讨论】:
+1 谢谢。这给了我一些东西来看看并开始尝试理解。您是否知道任何可以建议多个线程的软件工具? 我认为每个 CPU 内核使用一个线程是一个明智的选择,但这实际上取决于您要解决的问题。 +1 每个内核一个,很难模拟数百个设备 如果您使用的是网络设备,那么无论如何所有数据都将以串行方式发送,所以我想那里不会有性能提升。我认为也许不需要有很多线程,您可以使用一个来继续发送数据,另一个来读取结果并确定响应属于哪个请求,而不是让大量空闲线程一次发送数据并等待回复.【参考方案2】:通常,真正并发运行的线程数取决于您拥有的 CPU 和 CPU 内核(包括超线程)的数量。也就是说,在任何给定时间,运行的线程数(在操作系统中)都等于“内核”的数量。
您可以在应用中同时运行多少线程取决于很多因素。最好的(外行)数字是机器上的内核数,但当然这就像假装没有其他人(没有其他应用程序)存在:)。
坦率地说,我想说对 .NET/Windows 中的多线程进行更多研究,因为当一个人没有真正扎实的理解时,往往会造成更多的“损害”而不是好处。 .NET 有线程池的概念,除了 Windows 之外,您还需要知道它是如何工作的。
在 .NET 3.5/4.0 中,您应该查看任务 (Task Parallel Library),因为该库在确定要生成多少线程(如果有的话)方面做得更好。有了 TPL,线程池得到了大修,它在生成线程和任务窃取等方面变得更加智能。但是您通常使用任务而不是线程。
这是一个复杂的领域,因此,.NET 框架引入了任务,以便将程序员从线程中抽象出来,因此允许运行时对此很聪明,而程序员只说她想要什么,而不是怎么做去做吧。
【讨论】:
+1 是的,我担心我可能造成的伤害多于好处。我也会看任务,谢谢 我发现区分术语“并发”和“并行”(即您所说的“真正并发”)很有用。【参考方案3】:运行密集型任务时的一个很好的经验法则是运行与物理核心数相同的数量。
是的,您可以运行更多任务,但它们会等待资源(或线程池中的线程),而您的盒子,无论大小,都无法将所有 cpu 核心资源 100% 的时间分配给一个线程由于后台/其他进程。因此,您实例化的任务越多,产生的线程就越多,因为它们超过了实际可能的并发线程(每个内核 1 个),就会发生更多的资源管理、排队和交换。
我现在使用病毒模式启动额外任务时所做的一项测试发现,最佳值非常接近作为上限的 CPU 计数。以一对一的比例启动的任务与物理核心计数的运行时间约为每个任务 1 分钟才能完成。设置为 CPU 计数的两倍,任务时间从平均 1 分钟变为平均约 5 分钟。启动超过核心数量的任务越多,它的速度就越慢。
因此,例如,如果您有 8 个物理内核,则 8 个任务(并且使用 TPL,在活动进程中本质上是 8 个并发线程)应该是最快的。有您的主线程或进程创建其他任务和其他后台进程,但如果该框为您的资源开发乐趣而完全隔离,那么这些将相当少。
当您将任务从队列或列表中剔除时,根据核心数量对任务上限进行编程的好处是,当您将应用程序部署到不同大小的盒子上时,它会自动调整自身。
为了以编程方式确定这一点,我们使用
var CoreCount = System.Environment.ProcessorCount / 2;
你问为什么要除以二?因为几乎所有现代处理器都使用逻辑内核或超线程。您应该通过自己的测试发现,如果您使用逻辑计数,则每个任务的总体速度以及整个过程都会显着下降。物理核心是关键。我们找不到快速查找物理与逻辑的方法,但对我们的盒子的快速调查发现这始终是正确的。 YMMV,但这可能会让你非常快。
【讨论】:
【参考方案4】:每个线程消耗更多内存(内核堆栈、线程环境块、线程本地、堆栈......)。 AFAIK 在 Windows 中没有明确的限制,因此约束将是内存(可能是每个线程的堆栈)。
在 Linux 中,线程更像是进程(具有共享内存),并且您受到以下因素的限制:
cat /proc/sys/kernel/threads-max
【讨论】:
【参考方案5】:这在很大程度上取决于机器 - CPU 和内存是主要的限制因素(尽管可能会受到操作系统限制)。
对于 .NET,thread pool 配置也开始发挥作用。
【讨论】:
【参考方案6】:根据我自己的经验,在使用线程时,提高 CPU 绑定进程性能的一个很好的经验法则是使用相同数量的线程作为内核,除非是在超线程系统的情况下,在这种情况下应该使用核心数的两倍。可以得出的另一条经验法则是针对 I/O 绑定进程。这条规则是将每个内核的线程数增加四倍,除了超线程系统的情况外,每个内核的线程数可以增加四倍。
【讨论】:
Lolx - 当我第一次发帖时,没有多核 CPU 之类的东西:-) 感谢您的建议 +1【参考方案7】:在我的 CPU 蜂鸣器响起之前,我能够在我当前的旧 CPU (2005) 上同时运行 4 个线程(使用 EVGA 的 CPU 刻录机)(在 Bios 菜单中编程)这意味着我达到了 90*c 以上。请记住,我们谈论的是同时工作的数据线程。一个很好的例子是同时打开多个程序。但总的来说,这真的取决于你的 CPU 在多任务处理方面有多好。 (换句话说,可以处理许多活动线程)一个安全的测试方法是下载“ocscanner (By EVGA)”和“CPU Thermometer”,使用 OC Scanner 内的 CPU 刻录机测试时,确保您的温度不超过 90* c(或您认为安全的任何温度)并查看您当前运行的线程数抛出了您的 CPU。从 2 个线程开始,等待 3-5 分钟,同时观察 CPU 温度,添加另一个线程,重复。 (不要碰运气!!!)(如果 CPU 温度计无法检测到您的温度,请不要尝试!!!)
【讨论】:
以上是关于我可以同时运行多少个线程?的主要内容,如果未能解决你的问题,请参考以下文章