Links

01.合适的线程数量

多线程挺好 但是并不是越多越好 线程也是有消耗的 iOS主线程堆栈大小1m,子线程512kb,并且不能通过编译器开关或线程API函数来更改

最优线程数计算理论依据

  • 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)
To determine the number of threads, we need to know two things:
• The number of available cores
• The blocking coefficient of tasks
The first one is easy to determine; we can look up that information, even at
runtime, as we saw earlier. It takes a bit of effort to determine the blocking
coefficient. We can try to guess it, or we can use profiling tools or the java.
lang.management API to determine the amount of time a thread spends on
system/IO operations vs. on CPU-intensive tasks.
  • 线程数 = 可用核数 / (1 - 阻塞系数 )
  • 阻塞系数 = 阻塞时间 / (阻塞时间 + CPU使用时间)

网友的一点补充

其实,如果全系统只运行你一个程序,只考虑测试代码,阻塞系数是0.5,当然是没错的,但是这个公式是针对全系统而言的,需要把全系统所有程序的线程占用的timeslice都计算在内考虑。理论计算是需要考虑所有细节的,这些细节占用的时间可一点不少哦。
当全系统线程数量远远大于执行核心数,则增加了线程的上下文环境交换时间等等,还有其他线程分走了许多CPU时间片,这部分时间可不少,可是却没有用在你的测试计算上。为简化理解,直接把这部分时间都划算到阻塞时间上,等于说阻塞系数变大,纯工作系数变小;分母就变小了,最佳线程数量就成倍增大了。
如果还不理解,我举个例子,用实际场景来解释就明白了。
一个加工厂有4条加工流水线,每一个人同时只能占用一条流水线加工自己的产品,假定一个人占据一条加工流水线完全饱和工作8小时能完成自己的加工,那么拆分到4条线上显然2小时可以加工完成,理论上。
再假定人的饱和工作时间和空闲时间各占50%呢(构造阻塞系数0.5),在不考虑交班交接的时间,显然8个人同时排队加工才能这2小时完成,(加工厂只安排你的8个人)。
但是事实工厂工况是怎么样的呢?这个加工厂有1000人在排队等着加工自己的产品(你安排了8个人过去加工你的产品 + 992个外人),而且,一条流水线线上工作内容切换时,前一个人和后一个人交替交接需要占用不少时间,而且,992个外人也各自要加工自己的产品,分配给你那8个人的时间片机会就少了。为简化理解,那些时间都没为你的产品加工,都直接是划归到阻塞时间上去,阻塞系数变大,最佳线程数=CPU执行核心数/(1-阻塞系数), 分母变小,结果自然变大。如果你要获得更多的时间片,你就要安排更多人过去,增大占时间片的机会。
所以你安排8个人去加工,肯定2小时完成不了,可能实际用了3小时才加工完成。但是你若安排16个人过去排队加工,可能2.5小时就能加工完成了。

参考

Last modified 3yr ago