虽说是 cpu 密集型,但是也会有一些如打印日志这样的 io 操作,而且 logback 日志底层是堵塞的。 那么线程数应该等于核心数还是核心数+1 呢??
执行 cpu 密集型操作,使用线程池数量等于 cpu 核心数,任务跑起来后,cpu 占用只能到 80%左右,无法充分利用。 猜测是因为任务中的日志部分涉及到资源堵塞和同步。
增大一个线程数,好处是能利用其他线程输出日志堵塞时的 cpu 资源,缺点是增大了线程上下文切换消耗的资源。
当节省的资源 > 消耗的资源时,增大线程数是划算的,否则不划算。
|      1jdjingdian      2021-08-05 14:03:33 +08:00 同问,因为经常看到开源项目编译命令推荐用“make -j $(($(nproc) + 1))”,不是很明白为什么要要比 CPU 线程数多 1 | 
|  |      2wowo243      2021-08-05 14:17:57 +08:00 | 
|  |      4jdhao      2021-08-05 14:34:40 +08:00 via Android CPU 密集型任务不是应该使用多进程? 你用多线程能使用多核的能力吗。一般多线程应该是用于网络 io 密集型场景。 进程数太多不一定是好的,需要根据自己的任务做 benchmark | 
|  |      5lithiumii      2021-08-05 14:44:28 +08:00 核心数呗,省下来的一点点利用率用于万一卡死了 ssh 还能连上去看看发生了什么( | 
|  |      6wanguorui123      2021-08-05 14:49:56 +08:00 多加几条没问题,比较关键的应用优先级调高点,防止分不到时间片卡死 | 
|      8Leviathann      2021-08-05 15:00:29 +08:00 @jdhao CPU 密集必须多进程的不是 python 吗。。 | 
|  |      9777777      2021-08-05 15:07:16 +08:00 用 go,不用管线程 | 
|  |      10tabris17      2021-08-05 15:12:17 +08:00 经验?我看到还有说 CPU*2 的呢 | 
|  |      11ikas      2021-08-05 15:35:41 +08:00 ...这个肯定要看具体的用途..比如你的任务都是很快就执行完的..那线程就可以配置为 cpu 内核数量(左右),因为相当于每个线程一直在处理,不停顿..如果你的任务是有 io 相关,需要等待的..这时候你的线程数量限制主要是要考量你的内存能支持开多少个. | 
|  |      12cubecube      2021-08-05 15:56:15 +08:00 @tabris17 *2 肯定不是 cpu 密集型了。。 其实有一个公式,就是算 io 和 cpu 的占比算的,我记得美团有个文章结过 https://p0.meituan.net/travelcube/23a44974ff68a08261fb675242b83648181953.png | 
|  |      13Cloutain      2021-08-05 16:20:00 +08:00 建议协程 | 
|      14iceheart      2021-08-05 16:31:09 +08:00 via Android  1 还得看负载啊 | 
|  |      18sununiq      2021-08-05 17:07:06 +08:00 ```java benchmark ``` | 
|      20rayw0ng      2021-08-05 18:06:40 +08:00 kotlin coroutine 的 Dispatcher 默认线程数 = CPU 核心数,Dispatcher.IO 默认线程数 = 64,仅供参考。 | 
|  |      21leeyom      2021-08-05 18:32:10 +08:00 io 密集型一般设置线程数 cpu 核心数*2 cpu 密集型一般设置线程数 cpu 核心数+1 或者 -1 吧 毕竟 cpu 密集型你线程数创建太多,上下文切换很浪费时间吧 | 
|      22securityCoding      2021-08-05 18:35:50 +08:00 @iceheart +1 这个只是经验值而已,要得到准确的数值还得靠压测. 像很多 rpc 框架 io 线程数有的都给到 200 了 | 
|  |      25rb6221      2021-08-05 22:01:19 +08:00 理论要结合实践,如果你要做到完美那就是不同的项目应该使用不同的数量,就像楼上某一层回复说的,流量分布不平均都可能有不同的值,这意味着每一秒都可能有一个自己的最佳值,这种情况下你是无法做到完美的。所以只有两种方法 第一是使用别人提供的建议值,不完美但是很接近完美 第二是跑分,自己确定自己的项目应该使用的值。 但是还是要记住 无论哪一个都做不到完美 | 
|      26gBurnX      2021-08-06 00:48:35 +08:00 1.计算机科学是一门工程学,而并非理论学科。所以,算法、各种分布式理论、人工智障等等,那些书本里的东西,也是工程经验的产物,你应付考试了解一下就行了,不要尽信。 2.实际工程,并不是非黑即白,比如全是 CPU 密集型,或者全是日志打印这种非 CPU 密集型。你要根据项目实际的情况,去收集具体任务执行情况,分析两种具体任务的百分比、执行顺序等等多种因素。 3.判断一项原理的优缺点,也要看大局。比如很多人觉得 Python 性能差,但很多应用 Python 的地方,并不差钱,他们追求的是最高的开发效率,以及尽量集中注意力到业务上而非各种细节优化上。 | 
|  |      27msg7086      2021-08-06 00:54:05 +08:00 via Android @jdhao 只有有全局线程锁 GIL 的语言才会被线程束缚。 Python 和 Ruby 这类语言(的官方实现)才是特例。大部分语言实现都是没有这种强制线程锁的,多线程设计出来本来就是用来占满 CPU 资源的。 | 
|      28chenqh      2021-08-06 01:36:12 +08:00 | 
|  |      29msg7086      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 也是设计之初就没有考虑多线程。他们都是有特殊的应用场景的。 | 
|  |      32Brentwans      2021-08-06 17:22:00 +08:00 密集型的计算,核心数还是核心数+1 。偏向于+1,因为现实中 CPU 太快了,再密集的计算都难免有内存带来的延迟,增加一个来充分利用 CPU 。 如果只是为了应用,得到合适的线程数,那实际情况远不是理论上一个公式那么简单,这个场景跑 benchmark 得出是最靠谱的。 但是看了你这个问题描述,好像你或许不是需要多少个线程数,而是定位目前性能上不去的瓶颈是什么?还是先 profile 找到瓶颈点再去找解决方案吧 | 
|      33goobai      2021-08-06 18:16:42 +08:00 via Android 我咋觉得 cpu 密集型任务不应该超过核心数呢?是我太菜吗? |