首页 文章

每个核心的最佳线程数

提问于
浏览
238

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

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

Is there a benefit to running a parallelizable process on more threads than cores? In other words, will my process finish faster, slower, or in about the same amount of time if I run it using 4000 threads rather than 4 threads?

13 回答

  • 21

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

  • 218

    理想情况是每个核心有1个线程,只要没有线程会阻塞 .

    一种情况可能不是这样:核心上还有其他线程运行,在这种情况下,更多线程可能会给你的程序更大的执行时间 .

  • 0

    一次有4000个线程非常高 .

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

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

  • 0

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

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

  • 6

    您可以通过运行htop或ps命令来查找机器上可运行的线程数,该命令可返回机器上的进程数 .

    您可以使用有关'ps'命令的手册页 .

    man ps
    

    如果要计算所有用户进程的数量,可以使用以下命令之一:

    • ps -aux| wc -l

    • ps -eLf | wc -l

    计算用户进程的编号:

    • ps --User root | wc -l

    此外,您可以使用"htop" [Reference]

    在Ubuntu或Debian上安装:

    sudo apt-get install htop
    

    在Redhat或CentOS上安装:

    yum install htop
    dnf install htop      [On Fedora 22+ releases]
    

    如果你想从源代码编译htop,你会发现here .

  • 117

    许多线程(“线程池”)与每个核心一个的一个例子是在Linux或Windows中实现Web服务器 .

    由于套接字在Linux中被轮询,因此许多线程可能会增加其中一个线程在正确的时间轮询正确套接字的可能性 - 但总体处理成本将非常高 .

    在Windows中,服务器将使用I / O完成端口 - IOCP实现 - 这将使应用程序事件驱动:如果I / O完成操作系统启动备用线程来处理它 . 当处理完成时(通常使用请求 - 响应对中的另一个I / O操作),线程返回到IOCP端口(队列)以等待下一个完成 .

    如果没有完成I / O,则不进行任何处理,也不启动任何线程 .

    实际上,Microsoft建议在IOCP实现中每个核心不超过一个线程 . 任何I / O都可以附加到IOCP机制 . 如有必要,申请还可以发布IOC .

  • 2

    从计算和内存绑定的角度来讲(科学计算)4000个线程将使应用程序运行速度非常慢 . 问题的一部分是上下文切换的非常高的开销,并且很可能是非常差的内存局部性 .

    但它也取决于您的架构 . 从我听说Niagara处理器假设能够使用某种先进的流水线技术处理单个核心上的多个线程 . 但是我对这些处理器没有经验 .

  • 2

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

    enter image description here

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

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

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

  • 40

    希望这是有道理的,检查CPU和内存利用率并设置一些阈值 . 如果超过阈值,则不允许创建新线程,否则允许...

  • 16

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

    来自Wikipedia

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

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

    如果问题是假设弱缩放,那么@Gonzalo 's answer suffices. However if the question is assuming strong scaling, there'要添加更多内容 . 在强扩展中,您假设工作负载大小固定,因此如果增加线程数,则每个线程需要处理的数据大小会减小 . 在现代CPU上,内存访问非常昂贵,并且通过将数据保存在缓存中来维护本地性更为可取 . 因此,可以找到可能的最佳线程数 when the dataset of each thread fits in each core's cache (系统的I / 459185_s L1 / L2 / L3缓存) .

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

    Case 1: 运行四个线程,每个线程需要完成2AU . 每个线程需要10秒才能完成( with a lot of cache misses ) . 使用四个内核时,总时间将为10秒(10秒* 4线程/ 4个内核) .

    Case 2: 运行八个线程,每个线程需要完成1AU . 由于 reduced amount of cache misses ,每个线程只需2秒(而不是5秒) . 使用8个内核时,总时间将为4秒(2s * 8个线程/ 4个内核) .

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

  • 7

    基准 .

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

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

    在测试之前你无法知道 .

  • 7

    我知道这个问题相当陈旧,但自2009年以来事情已经发生了变化 .

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

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

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

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

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

  • 3

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

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

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

相关问题