估算线程池大小和吞吐量的方法

估算吞吐量

吞吐量计算公式:

img

如下,单核cpu,开启10个线程,共运行10个任务。

img

throughput = 10 tasks / (10 * computing time + wait time) 
           = 10 tasks / (10 * 1s + 9s) 
           = 10 / 19s = 0.526 tasks/s

如下,双核cpu,运行10线程,10个任务,则计算速度缩小一半。

throughput = 10 tasks / (10 * computing time / 2 + wait time) 
           = 10 tasks / (10 * 1s / 2 + 9s) 
           = 10 / 14s = 0.7142 tasks/s

估算线程池大小

那么问题来了,如何知道要开多少个线程能够让CPU达到目标利用率?

这个要看下面的公式:

img

注:本公式里的 N * U = 吞吐量公式中的C。

如果U=1(利用率100%),决定线程数量的是W与C的比,当W越高时则需要越多的线程,当W=0时,只需要与N同样的线程即可。

这样一分析,下面这段话就好理解了

“性质不同的任务可以用不同规模的线程池分开处理。CPU密集型任务应配置尽可能小的线程,如配置Ncpu+1个线程的线程池。由于IO密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程,如2Ncpu。混合型的任务,如果可以拆分,将其拆分“是一直在执行任务,则应配置尽可能多的线程,如2Ncpu。混合型的任务,如果可以拆分,将其拆分成一个CPU密集型任务和一个IO密集型任务,只要这两个任务执行的时间相差不是太大,那么分解后执行的吞吐量将高于串行执行的吞吐量。如果这两个任务执行时间相差太大,则没必要进行分解。”

《Java并发编程的艺术》