以下是 Java Concurrency in Practice 一书的节选,第 12.2 章性能测试,作者谈到了有界缓冲区实现的吞吐量。
图 12.1 显示了 4 路机器上的一些示例结果,使用的缓冲区容量为 1、10、100 和 1000。我们立即看到缓冲区大小为 1 会导致吞吐量非常低;这是因为每个线程在阻塞和等待另一个线程之前只能取得一点点进展。将缓冲区大小增加到 10 会有很大帮助,但增加超过 10 会带来收益递减。
一开始可能有点令人费解,添加更多线程只会稍微降低性能。原因很难从数据中看出,但在测试运行时在诸如 perfbar 之类的 CPU 性能计上很容易看出:即使有很多线程,也没有进行太多计算,大部分都花在阻塞和解除阻塞线程上. 因此,有足够的 CPU 空闲时间让更多线程执行相同的操作,而不会对性能造成太大影响。
但是,请注意从这些数据中得出的结论是,您始终可以向使用有界缓冲区的生产者-消费者程序添加更多线程。这个测试在模拟应用程序方面是相当人为的;生产者几乎不做任何工作来生成放置在队列中的项目,而消费者几乎不做任何工作来处理检索到的项目。如果真正的生产者-消费者应用程序中的工作线程做一些重要的工作来生产和消费项目(通常是这种情况),那么这种松弛就会消失,线程过多的影响可能会非常明显。该测试的主要目的是测量通过有界缓冲区进行的生产者-消费者切换对整体吞吐量施加的限制。
作者这里的cpu slack是什么意思?为什么随着线程数量的增加,吞吐量不会越来越下降?我没有遵循作者给出的关于在添加越来越多的线程时性能略有下降的推理,假设缓冲区大小的界限保持不变。
编辑:我能想到一个原因:因为在这种情况下,线程没有做任何实际工作,所以共享内存总线上流量增加的经典问题,由于线程的上下文切换导致的缓存未命中数并没有发挥主要作用随着越来越多的线程被添加。一旦线程开始做更多的工作,情况就会改变。这就是作者在第三段中试图表达的意思吗?