关于最佳线程数的计算的准确理解

Venkat Subramaniam 博士在《Programming Concurrency on the JVM》中提到关于最优线程数的计算:程序员

The minimum number of threads is equal to the number of available cores. If all tasks are computation intensive, then this is all we need. Having more threads will actually hurt in this case because cores would be context switching between threads when there is still work to do. If tasks are IO intensive, then we should have more threads. We can compute the total number of threads we’d need as follows:测试

Number of threads = Number of Available Cores / (1 - Blocking Coefficient)this

To determine the number of threads, we need to know two things:
• The number of available cores
• The blocking coefficient of tasks线程

根据描述,最佳线程数量=CPU执行核心数/(1-阻塞系数);ci

许多程序员就立马写个程序测试,模拟一个阻塞系数0.5的线程,硬件配置CPU执行核心数是4,刚好2倍核心数,最佳线程数量是8,而后就开8个线程去处理。测试完成任务处理时间是316ms。觉得这样是最佳了。而后又抱着怀疑的态度再作一轮测试,特地开16个线程去一跑,发现时间只用了215ms。更少了。咦?怎么回事呢?而后得出结论:最佳线程数量并不是最佳。 4倍才是最佳的。是这样吗?问题出在哪里了呢?产品

其实,若是全系统只运行你一个程序,只考虑测试代码,阻塞系数是0.5,固然是没错的,可是这个公式是针对全系统而言的,须要把全系统全部程序的线程占用的timeslice都计算在内考虑。理论计算是须要考虑全部细节的,这些细节占用的时间可一点很多。it

当全系统线程数量远远大于执行核心数,则增长了线程的上下文环境交换时间等等,还有其余线程分走了许多CPU时间片,这部分时间可很多,但是却没有用在你的测试计算上。为简化理解,直接把这部分时间都划算到阻塞时间上,等于说阻塞系数变大,纯工做系数变小;分母就变小了,最佳线程数量就成倍增大了。io

若是还不理解,我举个例子,用实际场景来解释就明白了。thread

一个加工厂有4条加工流水线,每个人同时只能占用一条流水线加工本身的产品,假定一我的占据一条加工流水线彻底饱和工做8小时能完成本身的加工,那么拆分到4条线上显然2小时能够加工完成,理论上。配置

再假定人的饱和工做时间和空闲时间各占50%呢(构造阻塞系数0.5),在不考虑交班交接的时间,显然8我的同时排队加工才能在2小时完成,(加工厂只安排你的8我的)。

可是事实工厂工况是怎么样的呢?这个加工厂有1000人在排队等着加工本身的产品(你安排了8我的过去加工你的产品 + 992个外人),并且,一条流水线线上工做内容切换时,前一我的和后一我的交替交接须要占用很多时间,并且,992个外人也各自要加工本身的产品,分配给你那8我的的时间片机会就少了。那些时间都没为你的产品加工,都直接是划归到阻塞时间上去,阻塞系数变大,最佳线程数=CPU执行核心数/(1-阻塞系数), 分母变小,结果天然变大。若是你要得到更多的时间片,你就要安排更多人过去,增大占时间片的机会。

因此你安排8我的去加工,确定2小时完成不了,可能实际用了3小时才加工完成。可是你若安排16我的过去排队加工,可能2.5小时就能加工完成了。

如此而已。

相关文章
相关标签/搜索