多线程 – 如何在4核CPU上更快地完成相同的计算:4个线程或50个线程?

前端之家收集整理的这篇文章主要介绍了多线程 – 如何在4核CPU上更快地完成相同的计算:4个线程或50个线程?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
让我们假设我们有固定数量的计算工作,没有阻塞,睡眠,i / o等待.这项工作可以很好地并行化 – 它包含100M小型和独立的计算任务.

4核cpu的速度更快 – 运行4个线程还是……让我们说50?为什么第二种变体应该是摇摆不定的?

我假设:当你在4核cpu上运行4个重线程而没有另外占用cpu的进程/线程时,调度程序不允许在核心之间移动线程;在这种情况下,它没有理由这样做. Core0(主cpu)将负责执行硬件计时器的中断处理程序每​​秒250次(基本Linux配置)和其他硬件中断处理程序,但另一个核心可能不会感到任何担心.

上下文切换的成本是多少?存储和恢复cpu寄存器的时间是否适用于不同的上下文? cpu内部的缓存,管道和各种代码预测事项怎么样?我们可以说每次切换上下文时,都会损害cpu中的缓存,管道和一些代码解码功能吗?因此,在单个内核上执行更多线程,与串行执行相比,它们可以一起完成更少的工作?

关于多线程环境中的缓存和其他硬件优化的问题现在对我来说是个有趣的问题.

解决方法

正如@Baile在评论中提到的,这是高度应用,系统,环境特定的.

因此,我不打算采用强硬的方法为每个核心提及1个线程. (或超线程情况下的2个线程/核心)

作为一名经验丰富的共享内存程序员,我从我的经验中看到,最佳的线程数(对于4核机器)可以在1到64之间.

现在我将列举可能导致此范围的情况:

最佳线程<核心数量 在某些非常细粒度并行的任务(例如小FFT)中,线程的开销是主要的性能因素.在某些情况下,完全并行化并没有帮助.在某些情况下,您可以通过2个线程获得加速,但是在4个线程处向后扩展. 另一个问题是资源争用.即使您具有可以轻松分割为4个内核/线程的高度可并行化的任务,您也可能会遇到内存带宽和缓存效应的瓶颈.通常,您会发现2个线程与4个线程一样快. (好像经常出现非常大的FFT) 最佳线程=核心数 这是最佳情况.这里不需要解释 – 每个核心一个线程.大多数令人尴尬的并行应用程序都不适合内存或I / O绑定. <最佳线程>核心数量 这是它变得有趣的地方……非常有趣.你听说过负载不平衡吗?如何过度分解和偷工作? 许多可并行化的应用程序是不规则的 – 这意味着任务不会分成相同大小的子任务.因此,如果您最终可能将大型任务拆分为4个不相等的大小,请将它们分配给4个线程并在4个核心上运行…结果?并行性能差,因为1个线程的工作量比其他线程多10倍. 这里的常见解决方案是将任务过度分解为许多子任务.您可以为每个线程创建线程(现在您可以获得线程>>核心).或者您可以使用某种具有固定线程数的任务调度程序.并非所有任务都适用于两者,因此通常,将任务过度分解为4核机器的8或16个线程的方法可以获得最佳结果.

虽然产生更多线程可以带来更好的负载平衡,但是开销会增加.所以通常在某处有一个最佳点.我在4个核心上看到高达64个线程.但如上所述,它具有高度的应用特性.你需要进行实验.

编辑:扩大答案更直接回答问题…

What is the cost of context switching? The time for store and restore
cpu registers for different context?

这非常依赖于环境 – 并且有点难以直接测量.简答:非常昂贵的This might be a good read.

What about caches,pipelines and varIoUs code-prediction things inside
cpu? Can we say that each time we switch context,we hurt caches,
pipelines and some code-decoding facilities in cpu?

简短回答:是当您关闭上下文时,您可能会清空管道并弄乱所有预测变量.与缓存相同.新线程可能会用新数据替换缓存.

虽然有一个问题.在线程共享相同数据的某些应用程序中,一个线程可能会为另一个传入线程或另一个共享同一缓存的核心上的另一个线程“加热”缓存. (虽然很少见,我之前在我的一台NUMA机器上看到过这种情况 – 超线性加速:16个核心的17.6倍!?!?!)

So more threads executing on a single core,less work they can do
together in comparison to their serial execution?

取决于,取决于…除了超线程,肯定会有开销.但我读过一篇论文,其中有人使用第二个线程来预取主线程…是的,它很疯狂……

猜你在找的Java相关文章