cpu 密集型任务,线程数应该等于核心数还是核心数+1 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
git00ll
V2EX    Java

cpu 密集型任务,线程数应该等于核心数还是核心数+1

  •  1
     
  •   git00ll 2021-08-05 13:38:00 +08:00 6050 次点击
    这是一个创建于 1611 天前的主题,其中的信息可能已经有所发展或是发生改变。

    虽说是 cpu 密集型,但是也会有一些如打印日志这样的 io 操作,而且 logback 日志底层是堵塞的。 那么线程数应该等于核心数还是核心数+1 呢??

    现象

    执行 cpu 密集型操作,使用线程池数量等于 cpu 核心数,任务跑起来后,cpu 占用只能到 80%左右,无法充分利用。 猜测是因为任务中的日志部分涉及到资源堵塞和同。

    分析

    增大一个线程数,好处是能利用其他线程输出日志堵塞时的 cpu 资源,缺点是增大了线程上下文切换消耗的资源。

    当节省的资源 > 消耗的资源时,增大线程数是划算的,否则不划算。

    结论,尚未测试

    33 条回复    2021-08-06 18:16:42 +08:00
    jdjingdian
        1
    jdjingdian  
       2021-08-05 14:03:33 +08:00
    同问,因为经常看到开源项目编译命令推荐用“make -j $(($(nproc) + 1))”,不是很明白为什么要要比 CPU 线程数多 1
    wowo243
        2
    wowo243  
       2021-08-05 14:17:57 +08:00
    jdhao
        4
    jdhao  
       2021-08-05 14:34:40 +08:00 via Android
    CPU 密集型任务不是应该使用多进程? 你用多线程能使用多核的能力吗。一般多线程应该是用于网络 io 密集型场景。

    进程数太多不一定是好的,需要根据自己的任务做 benchmark
    lithiumii
        5
    lithiumii  
       2021-08-05 14:44:28 +08:00
    核心数呗,省下来的一点点利用率用于万一卡死了 ssh 还能连上去看看发生了什么(
    wanguorui123
        6
    wanguorui123  
       2021-08-05 14:49:56 +08:00
    多加几条没问题,比较关键的应用优先级调高点,防止分不到时间片卡死
    Geele
        7
    Geele  
       2021-08-05 14:53:42 +08:00
    @jdhao Java 多线程不能使用多核能力吗?
    Leviathann
        8
    Leviathann  
       2021-08-05 15:00:29 +08:00
    @jdhao CPU 密集必须多进程的不是 python 吗。。
    777777
        9
    777777  
       2021-08-05 15:07:16 +08:00
    用 go,不用管线程
    tabris17
        10
    tabris17  
       2021-08-05 15:12:17 +08:00
    经验?我看到还有说 CPU*2 的呢
    ikas
        11
    ikas  
       2021-08-05 15:35:41 +08:00
    ...这个肯定要看具体的用途..比如你的任务都是很快就执行完的..那线程就可以配置为 cpu 内核数量(左右),因为相当于每个线程一直在处理,不停顿..如果你的任务是有 io 相关,需要等待的..这时候你的线程数量限制主要是要考量你的内存能支持开多少个.
    cubecube
        12
    cubecube  
       2021-08-05 15:56:15 +08:00
    @tabris17 *2 肯定不是 cpu 密集型了。。
    其实有一个公式,就是算 io 和 cpu 的占比算的,我记得美团有个文章结过

    https://p0.meituan.net/travelcube/23a44974ff68a08261fb675242b83648181953.png
    Cloutain
        13
    Cloutain  
       2021-08-05 16:20:00 +08:00
    建议协程
    iceheart
        14
    iceheart  
       2021-08-05 16:31:09 +08:00 via Android   1
    还得看负载啊
    jdhao
        15
    jdhao  
       2021-08-05 16:32:05 +08:00 via Android
    @Geele Java 不太了解,Java 里面线程概念和其他似乎不一样
    dranfree
        16
    dranfree  
       2021-08-05 16:42:05 +08:00
    @jdhao 多线程就是为了充分利用 CPU 资源,怎么就不能使用多核能力了。。
    zavierx
        17
    zavierx  
       2021-08-05 16:45:09 +08:00
    @jdhao cpu 本来就是按线程调度的,为什么用不了多核?
    sununiq
        18
    sununiq  
       2021-08-05 17:07:06 +08:00
    ```java
    benchmark
    ```
    billlee
        19
    billlee  
       2021-08-05 17:19:28 +08:00
    @jdhao 这世上不是只有 cpython
    rayw0ng
        20
    rayw0ng  
       2021-08-05 18:06:40 +08:00
    kotlin coroutine 的 Dispatcher 默认线程数 = CPU 核心数,Dispatcher.IO 默认线程数 = 64,仅供参考。
    leeyom     21
    leeyom  
       2021-08-05 18:32:10 +08:00
    io 密集型一般设置线程数 cpu 核心数*2
    cpu 密集型一般设置线程数 cpu 核心数+1 或者 -1 吧
    毕竟 cpu 密集型你线程数创建太多,上下文切换很浪费时间吧
    securityCoding
        22
    securityCoding  
       2021-08-05 18:35:50 +08:00
    @iceheart +1
    这个只是经验值而已,要得到准确的数值还得靠压测. 像很多 rpc 框架 io 线程数有的都给到 200 了
    jdhao
        23
    jdhao  
       2021-08-05 18:49:27 +08:00 via Android
    @billlee 好的,我孤陋寡闻了,对 Java 线程不了解
    chevalier
        24
    chevalier  
       2021-08-05 21:07:59 +08:00
    @jdhao 不要让语言限制了你的认知,大多数语言( C++,Java,Golang )多线程都可以吃多核的
    rb6221
        25
    rb6221  
       2021-08-05 22:01:19 +08:00
    理论要结合实践,如果你要做到完美那就是不同的项目应该使用不同的数量,就像楼上某一层回复说的,流量分布不平均都可能有不同的值,这意味着每一秒都可能有一个自己的最佳值,这种情况下你是无法做到完美的。所以只有两种方法
    第一是使用别人提供的建议值,不完美但是很接近完美
    第二是跑分,自己确定自己的项目应该使用的值。
    但是还是要记住 无论哪一个都做不到完美
    gBurnX
        26
    gBurnX  
       2021-08-06 00:48:35 +08:00
    1.计算机科学是一门工程学,而并非理论学科。所以,算法、各种分布式理论、人工智障等等,那些书本里的东西,也是工程经验的产物,你应付考试了解一下就行了,不要尽信。

    2.实际工程,并不是非黑即白,比如全是 CPU 密集型,或者全是日志打印这种非 CPU 密集型。你要根据项目实际的情况,去收集具体任务执行情况,分析两种具体任务的百分比、执行顺序等等多种因素。

    3.判断一项原理的优缺点,也要看大局。比如很多人觉得 Python 性能差,但很多应用 Python 的地方,并不差钱,他们追求的是最高的开发效率,以及尽量集中注意力到业务上而非各种细节优化上。
    msg7086
        27
    msg7086  
       2021-08-06 00:54:05 +08:00 via Android
    @jdhao 只有有全局线程锁 GIL 的语言才会被线程束缚。
    Python 和 Ruby 这类语言(的官方实现)才是特例。大部分语言实现都是没有这种强制线程锁的,多线程设计出来本来就是用来占满 CPU 资源的。
    simple2025
        28
    simple2025  
       2021-08-06 01:36:12 +08:00
    @msg7086 不是大部分脚本语言多线程实现都有问题吗?

    python ruby gil

    php 的多线程好像也有问题

    nodejs 一开始根本就不支持线程

    lua 好像也没有线程吧
    msg7086
        29
    msg7086  
       2021-08-06 02:36:08 +08:00
    @chenqh Python 和 Ruby 也是“官方实现”才用到了 GIL 。
    换句话说只有 CPython 和 Ruby MRI 才有 GIL 的概念。
    Jython 和 JRuby 都是没有 GIL 的。Rubinius 也很早就移除了 GIL 。
    GIL 主要是省心,不用折腾 C 库的线程安全,解释器实现起来也方便。

    脚本语言原本也算是一种特例了。C/C++/Java/C#这些常用语言的实现都是没有 GIL 的。

    至于 PHP 和 JS 说起来就比较复杂了。PHP 本身是支持多线程的,但是语言实现内部没有做多线程,因为 PHP 原本就不是用来做 CPU 密集型任务的。PHP 的多线程是体现在调用端的,可以起一大堆单线程运行的 PHP 线程。JS 也是设计之初就没有考虑多线程。他们都是有特殊的应用场景的。
    leon0318
        30
    leon0318  
       2021-08-06 08:39:14 +08:00 via iPhone   3
    @Cloutain 都 cpu 密集型了,协程有啥用……
    Cloutain
        31
    Cloutain  
       2021-08-06 10:55:34 +08:00
    @leonme 尴尬了 不懂这一块
    Brentwans
        32
    Brentwans  
       2021-08-06 17:22:00 +08:00
    密集型的计算,核心数还是核心数+1 。偏向于+1,因为现实中 CPU 太快了,再密集的计算都难免有内存带来的延迟,增加一个来充分利用 CPU 。
    如果只是为了应用,得到合适的线程数,那实际情况远不是理论上一个公式那么简单,这个场景跑 benchmark 得出是最靠谱的。
    但是看了你这个问题描述,好像你或许不是需要多少个线程数,而是定位目前性能上不去的瓶颈是什么?还是先 profile 找到瓶颈点再去找解决方案吧
    goobai
        33
    goobai  
       2021-08-06 18:16:42 +08:00 via Android
    我咋觉得 cpu 密集型任务不应该超过核心数呢?是我太菜吗?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1258 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 16:52 PVG 00:52 LAX 08:52 JFK 11:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86