7

一切都完全是理论上的,这个问题刚刚浮现在脑海中,我不完全确定答案是什么:

假设您有一个计算 4 个独立计算的应用程序。(完全独立,不管你按什么顺序做,你不需要一个来计算另一个)。还假设这些计算很长(分钟)并且受 CPU 限制(不等待任何类型的 IO)

1) 现在,如果您有一台单处理器计算机,单线程应用程序在逻辑上将比(或相同)多线程应用程序更快。由于计算机一次不能用一个处理器做多于一件事,它会在上下文切换等方面“浪费”时间。到目前为止,一切都很好?

2)如果您有一台4 处理器计算机,则 4 线程很可能比单线程更快。正确的?您的计算机现在可以一次执行 4 个操作,因此将您的应用程序划分为 4 个线程是合乎逻辑的,并且它应该以 4 个计算中最长的时间完成。到现在还好吗?

3)现在我很困惑的实际部分 - 为什么我的应用程序会创建比可用处理器数量(实际上 - 内核)更多的线程?我已经编程并看到了创建数十个和数百个线程的应用程序,但实际上 - 对于普通计算机来说,完美的数字大约是 8?

PS我已经读过这个:线程与单线程 但没有安静地回答这个问题。

干杯

4

4 回答 4

5

为什么我的应用程序会创建比可用处理器数量(实际上是内核)更多的线程?

一个很好的理由是如果您有等待事件的线程。例如,您可能有一个生产者/消费者应用程序,其中生产者正在从某个数据流中读取数据,并且该数据以突发形式到达:一批中的数百(或数千)条记录,然后有一段时间没有任何记录,然后是另一个爆裂。假设您有一台 4 核机器。您可以有一个读取数据并将其放入队列的生产者线程,以及处理队列的三个消费者线程。

或者,您可以有一个生产者线程和四个消费者线程。大多数时候,生产者线程是空闲的,给你四个消费者线程来处理队列中的项目。但是,当数据流上有可用的项目时,其中一个消费者线程会被换出以支持生产者。

这是一个简化的示例,但与我在生产中的程序基本相似。

更一般地说,创建比处理单元更多的连续工作(即受 CPU 限制)线程(通常是 CPU 内核,尽管超线程的存在使水有点混)是没有任何意义的。如果您知道您的线程不会等待外部事件,那么n+1当您只有n内核时拥有线程最终会浪费时间进行线程上下文切换。请注意,这完全是在您的程序的上下文中。如果有其他应用程序和操作系统服务正在运行,您的应用程序的线程将不时换出,以便那些其他应用程序和服务可以获得时间片。但是有人假设,如果您正在运行 CPU 密集型程序,您将限制同时运行的其他应用程序和服务。

当然,最好的选择是设置测试。在 4 核机器上,使用 1、2、3、4、5……线程测试您的应用程序。Time 完成不同数量的线程所需的时间。我想你会发现在 4 核机器上,最佳点是 3 或 4;最有可能是 4,除非有其他需要大量 CPU 的应用程序或操作系统服务。

于 2014-09-11T14:38:50.653 回答
1

将线程添加到您的应用程序并不是严格意义上的性能提升。有时您希望或需要同时执行多个任务,因为这是构建程序的最合乎逻辑的方式。

举个例子,也许你正在写一个游戏引擎,如果你采用多线程的方法,你可能会有一个物理线程,一个图形线程,一个网络线程,一个用户输入线程,一个资源加载线程从磁盘等

James Baxters 的观​​点也非常正确。有时线程正在等待资源并且在它们访问所述资源之前无法进一步执行。只有与内核相同数量的线程,一个内核将被浪费。

于 2014-09-11T14:33:02.353 回答
1

我认为您假设所有程序都受 CPU 限制 - 请记住您的一些线程将等待 I/O(磁盘/网络/用户流量)。

于 2014-09-11T14:29:51.543 回答
1

我可以想出比内核更多的线程的一个原因是,如果某些线程需要与其他方交互……等待来自服务器的响应……从数据库中查询某些内容。这将允许线程休眠,直到提供答案。这样其他计算就不必等待了。在 4cores->4thread 中,线程将等待输入,这可能导致其他代码也必须等待

于 2014-09-11T14:31:02.570 回答