每个核心的最佳线程数

Jul*_*iet 265 parallel-processing cpu

假设我有一个4核CPU,我想在最短的时间内运行一些进程.这个过程理想上是可并行化的,所以我可以在无限数量的线程上运行它的块,每个线程花费相同的时间.

由于我有4个内核,我不希望通过运行比内核更多的线程来加速,因为单个内核只能在给定时刻运行单个线程.我对硬件知之甚少,所以这只是猜测.

在比线程更多的线程上运行可并行化的进程是否有好处?换句话说,如果我使用4000个线程而不是4个线程运行它,我的进程会更快,更慢,还是在大约相同的时间内完成?

Gon*_*alo 241

如果您的线程不进行I/O,同步等操作,并且没有其他任何操作,则每个内核1个线程将为您提供最佳性能.然而,很可能并非如此.添加更多线程通常会有所帮助,但在某些时候,它们会导致性能下降.

不久前,我正在一台2位四核机器上进行性能测试,该机器在Mono上运行ASP.NET应用程序,负载相当不错.我们使用了最小和最大线程数,最后我们发现对于该特定配置中的特定应用程序,最佳吞吐量介于36到40个线程之间.超出这些界限的任何事情表现都更糟 学过的知识?如果我是你,我会测试不同数量的线程,直到找到适合您应用的数字.

有一点是肯定的:4k线程需要更长时间.这是很多上下文切换.

  • 我认为Gonzalo的答案很好.我只想补充一点,你应该进行实验和测量.您的计划将与他或我的或其他任何人的计划不同,只有您自己计划行为的衡量标准才能正确回答您的问题.并行(或并发)程序的性能不是仅从第一原理得出好结论的领域. (20认同)
  • 在现实世界的场景中,你不应该感到惊讶.线程阻塞等待IO资源,如磁盘访问,网络等.还等待其他线程的非IO资源完成使用共享变量.您真正想要实现的是最小线程数,这样每个核心至少可以运行一个线程. (12认同)
  • +1,+回答:令我惊讶的是,拥有比核心更多的线程会带来更好的性能,尽管如果更多的线程意味着与竞争线程相比更大的时间份额,那么这是有道理的.我的应用程序可以检测性能差异并自动调整自身以获得最佳线程数,这将是一件好事. (5认同)
  • 每个核心1个线程不是最佳的.它需要稍微多一点,最好是两倍,因为如果线程暂时被阻止,这将允许另一个线程运行.即使只是在记忆中.如果您拥有以SMT/HT为特色的系统(P4,I7,Sun Rock等),这将更加重要 (4认同)

Mot*_*sim 123

我同意@ Gonzalo的回答.我有一个不进行I/O的过程,这是我发现的:

在此输入图像描述

请注意,所有线程都在一个数组上工作,但不同的范围(两个线程不访问相同的索引),因此如果它们在不同的数组上工作,结果可能会有所不同.

1.86机器是带有SSD的macbook air.另一台mac是带普通硬盘的iMac(我认为是7200转).Windows机器也有一个7200转的硬盘驱动器.

在此测试中,最佳数量等于机器中的核心数量.

  • -1为图表!通过整数值x坐标平滑曲线?野外跳跃从1 2 3到10 20 30到50 100?并且y坐标是10加2的倍数以获得良好的度量.这是Excel的做法,不是吗? (44认同)
  • @PascalvKooten,问题不在于它看起来很漂亮,它乍一看是骗人的.首先,y轴从42开始,夸大了测试机器之间的明显差异.其次,x轴值的奇怪进展表明'时间'不会与'线程数'成线性关系,对于蓝线尤其如此.我认为其他人(包括我自己)所遇到的问题是它误报了数据. (19认同)
  • 图表+1.很明显,每个核心1个线程是最好的,但有趣的是,四核系统似乎不像其他人那样处于更高的线程数(<100). (14认同)
  • @Spacedman对图表的批评是我在过去24小时内遇到的最荒谬的事情.该图有所帮助.很多.期.可以做得更好吗?没人在乎.平滑曲线而不是离散?那是你的问题???? 我假设,你们所有人都不会在他们的答案中包含这样的图表,因为你没有额外的时间/精力来使它看起来很好.这是我的观点. (10认同)
  • @Spacedman是的.平滑的曲线有更好的外观恕我直言.:d (4认同)
  • 应该"线程数"是"每个核心的线程数"..? (2认同)
  • @joran图表有什么问题?我们都知道他们是整数,我仍然喜欢它的外观:-)它确实是Excel吗? (2认同)

Ale*_*lke 48

我知道这个问题相当陈旧,但自2009年以来情况有所发展.

现在需要考虑两件事:核心数量以及每个核心内可以运行的线程数量.

对于Intel处理器,线程数由超线程定义,仅为2(如果可用).但即使不使用2个线程,超线程也会将执行时间缩短两倍!(即在两个进程之间共享一条管道 - 当你有更多进程时这是好的,否则就不那么好了.更多内核肯定更好!)

在其他处理器上,您可能有2个,4个甚至8个线程.因此,如果您有8个内核,每个内核支持8个线程,则可以并行运行64个进程而无需上下文切换.

如果您使用标准操作系统运行,"无上下文切换"显然不正确,该操作系统将针对您无法控制的各种其他事情进行上下文切换.但那是主要的想法.某些操作系统允许您分配处理器,因此只有您的应用程序才能访问/使用所述处理器!

根据我自己的经验,如果你有很多I/O,多线程是好的.如果你有非常繁重的内存密集型工作(读取源1,读取源2,快速计算,写入),那么拥有更多线程无济于事.同样,这取决于您同时读取/写入多少数据(即,如果您使用SSE 4.2并读取256位值,则会停止其步骤中的所有线程...换句话说,1个线程可能更容易实现,并且如果不是实际上更快,可能几乎同样快速.这将取决于您的进程和内存架构,一些高级服务器管理单独内核的单独内存范围,因此假设您的数据正确归档,单独的线程将更快...这就是为什么,在某些体系结构,4个进程运行速度比1个进程运行速度快4个.)

  • 可能还有其他人,但我所知道的是来自IBM的POWER处理器.他们的系统每个处理器有4个或8个线程.现在他们可以使用更多核心,因此它们每个核心提供2个线程而不是...... (4认同)
  • 处理器没有线程.它们具有物理和逻辑核心.通过超线程,单个物理核心可用作两个逻辑核心.我有一个技术坚持认为具有线程的处理器是真实的,所以我在处理器的白板上绘制了一张图片,其中有一些线轴伸出它. (4认同)
  • @TechnikEmpire看看这个http://www.intel.com/content/www/us/en/processors/core/core-i7-processor.html,也许你可以联系英特尔并绘制它们的线程。 (2认同)

Jim*_*son 24

实际表现将取决于每个线程将自愿产生多少收益.例如,如果线程根本不进行I/O并且不使用系统服务(即它们是100%cpu绑定的),那么每个核心1个线程是最佳的.如果线程执行任何需要等待的操作,那么您将不得不尝试确定最佳线程数.4000个线程会产生大量的调度开销,因此这可能也不是最优的.


小智 19

答案取决于程序中使用的算法的复杂性.我想出了一种方法,通过对两个任意数量的线程'n'和'm'进行两次处理时间Tn和Tm来计算最佳线程数.对于线性算法,最佳线程数将是N = sqrt((m n(Tm*(n-1)-Tn*(m-1)))/(n Tn-m Tm)).

请阅读我关于各种算法的最佳数量计算的文章:pavelkazenin.wordpress.com

  • 它为什么被投票?对不起,这是这个问题的最佳答案.gonzalo解决了问题的大胆部分,pkazen解决了这个问题.这两个答案都非常有用,但是pkazen答案是相关的,因为我们有一个系统的方法来估计线程的数量.他甚至给出了linea算法的公式. (4认同)
  • 我没有投反对票,但如果我这样做,那就是没有真正的解释为什么或如何最佳线程数可能与算法的复杂性相关,除了阅读整个链接的文章之外,是一篇很长的文章(因为文章的复杂性)。除此之外,我不清楚这篇文章的某些方面,最重要的是实验结果如何证实该理论。 (2认同)

som*_*eat 9

我想我会在这里添加另一个视角.答案取决于问题是假设弱缩放还是强缩放.

来自维基百科:

弱缩放:解决方案时间如何随每个处理器的固定问题大小的处理器数量而变化.

强缩放:解决方案时间如何随固定总问题大小的处理器数量而变化.

如果问题是假设缩小,那么@ Gonzalo的答案就足够了.但是,如果问题是假设强大的缩放,那么还有更多要补充的内容.在强扩展中,您假设工作负载大小固定,因此如果增加线程数,则每个线程需要处理的数据大小会减小.在现代CPU上,内存访问非常昂贵,并且通过将数据保存在缓存中来维护本地性更为可取.因此,当每个线程的数据集适合每个核心的缓存时,可以找到可能的最佳线程数(我不会详细讨论它是否是系统的L1/L2/L3缓存).

即使线程数超过核心数,这也适用.例如,假设程序中有8个任意单位(或AU)的工作将在4核机器上执行.

情况1:运行四个线程,每个线程需要完成2AU.每个线程需要10秒才能完成(有很多缓存未命中).使用四个内核时,总时间将为10秒(10秒*4线程/ 4个内核).

案例2:运行八个线程,每个线程需要完成1AU.每个线程只需2秒(而不是5秒,因为缓存未命中数量减少).使用8个内核时,总时间将为4秒(2s*8个线程/ 4个内核).

我已经简化了问题并且忽略了其他答案中提到的开销(例如,上下文切换),但是希望你得到的结论是,拥有比可用核心数更多的线程可能是有益的,这取决于你的数据大小.重新处理.


Ear*_*rlz 7

一次有4000个线程非常高.

答案是肯定的,不是.如果你在每个线程中做很多阻塞I/O,那么是的,你可以显示出显着的加速,每个逻辑核心可能有3或4个线程.

但是,如果你没有做很多阻塞事情,那么线程的额外开销只会让它变慢.因此,请使用分析器,查看每个可能平行的部件中瓶颈的位置.如果您正在进行繁重的计算,那么每个CPU超过1个线程将无济于事.如果你正在进行大量的内存传输,它也无济于事.如果您正在进行大量的I/O,例如磁盘访问或Internet访问,那么多个线程将在一定程度上提供帮助,或者至少使应用程序更具响应性.


mmr*_*mmr 6

基准.

我开始增加应用程序的线程数,从1开始,然后转到100,为每个线程数运行三到五次试验,并自己构建一个运行速度与线程数的图表.

您应该认为四线程情况是最优的,之后运行时略有上升,但可能不是.可能是您的应用程序带宽有限,即您加载到内存中的数据集很大,您获得了大量缓存未命中等,因此2个线程是最佳的.

直到你测试才能知道.