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