线程池中如何确定线程的数目


  Nthreads=Ncpu*(1+w/c)

  IO密集型:如果存在IO,那么肯定w/c>1(阻塞耗时一般是计算耗时的很多倍),但是需要考虑系统内存有限(每开启一个线程都需要内存空间),这里需要上服务器测试具体多少个线程数适合(CPU占比、线程数、总耗时、内存消耗)。如果不想去测试,保守点取1即,Nthreads=Ncpu*(1+1)=2Ncpu+1。

  计算密集型:假设没有等待w=0,则W/C=0. Nthreads=Ncpu+1。在拥有N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的效率。(即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。)

 

  如果一台服务器上只部署这一个应用并且只有这一个线程池,那么这种估算或许合理,具体还需自行测试验证。

  服务器性能IO优化 中发现一个估算公式

  最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

  比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32。这个公式进一步转化为:

  最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目

 可以得出一个结论:

                          线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程

  一个系统最快的部分是CPU,决定一个系统吞吐量上限的是CPU。增强CPU处理能力,可以提高系统吞吐量上限。但根据短板效应,真实的系统吞吐量并不能单纯根据CPU来计算。那要提高系统吞吐量,就需要从“系统短板”(比如网络延迟、IO)着手:

  • 尽量提高短板操作的并行化比率,比如多线程下载技术
  • 增强短板能力,比如用NIO替代IO

  第一条可以联系到Amdahl定律,这条定律定义串行系统并行化后的加速比计算公式:

  加速比=优化前系统耗时 / 优化后系统耗时

  加速比越大,表明系统并行化的优化效果越好。Addahl定律还给出系统并行度CPU数目加速比的关系,加速比为Speedup系统串行化比率(指串行执行代码所占比率)为FCPU数目为N

  Speedup <= 1 / (F + (1-F)/N)

  当N足够大时,串行化比率F越小,加速比Speedup越大。

  是否使用线程池就一定比使用单线程高效呢?

  答案是否定的,比如Redis就是单线程的,但它却非常高效,基本操作都能达到十万量级/s。从线程这个角度来看,部分原因在于:

  • 多线程带来线程上下文切换开销,单线程就没有这种开销

  当然“Redis很快”本质的原因在于:Redis基本都是内存操作,这种情况下单线程可以很高效地利用CPU。而多线程适用场景一般是:存在相当比例的IO和网络操作。

所以即使有上面的简单估算方法,也许看似合理,但实际上也未必合理,需要结合系统真实情况(比如是IO密集型或者是CPU密集型或者是纯内存操作)和硬件环境(CPU、内存、硬盘读写速度、网络状况等)来不断尝试达到一个符合实际的合理估算值。

  

      参考:

  http://ifeve.com/how-to-calculate-threadpool-size/

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM