穿线很多会导致颠簸吗?

时间:2015-07-09 06:13:20

标签: multithreading cpu-usage

如果每个新线程想要访问内存(在我的情况下特别是相同的数据库)并在其生命周期内执行读/写操作,那么线程是否会导致颠簸?

我认为这是真的。如果我的假设是正确的,那么最大化CPU利用率的最佳方法是什么?我如何确定某些特定数量的线程将提供良好的CPU利用率?

如果我的假设是错误的,请给出适当的插图,让我清楚地了解情景。

2 个答案:

答案 0 :(得分:2)

Trashy代码导致垃圾邮件。不是线程。所有代码都由一些线程运行,甚至是main()。临时对象在任何线程上都以相同的方式进行垃圾收集。

细微的部分是每个线程预加载自己的对象以执行工作,这可以复制许多相同的类。它通常是一个小小的牺牲,以获得并发的力量。但它不是垃圾(没有泄漏,没有恶化)。

有一个例外:当一些第三方代码在线程本地缓存材料时......你可能最终在每个线程上缓存相同的东西。不是真的泄漏,但效率不高。

线程数的经验法则?取决于任务。

如果任务是像数学这样的纯计算,那么你不应该超过非超线程核心的数量。

如果作业是内存密集型以及纯计算工作(大多数情况下),则超线程内核的数量是您的目标(因为CPU将使用内存访问的空闲时间进行其他核心计算)。

如果作业大多是大顺序磁盘i / o,那么你的线程数应该不高于可读磁盘主轴的数量。这非常接近,因为磁盘缓存,DMA,SSD,raid等完全影响磁盘层如何在没有空闲的情况下为您的线程提供服务。使用随机访问时,这也是有效的。但是,如今的虚拟化将把所有的估算都抛到脑后。磁盘i / o可能比你想象的要多得多,但也更糟糕。

如果这些工作主要是网络I / O等待,那么它并不是真正受到限制;我将使用大约3倍的内核数量来启动。这个乘数只是假设这样的线程在网络上等待2/3的时间。这在实践中非常低。可能有99%的时间等待nw i / o(100x)。这就是为什么你到处都看到NIO套接字,用更少的繁忙线程来处理许多连接。

答案 1 :(得分:1)

不,你可以有100个空闲线程等待工作而没有看到任何颠簸,这是由应用程序工作集大小超过可用内存大小引起的,所以活动页面需要从磁盘重新加载(甚至写入当临时变量存储需要保存以便稍后重新编码时,将磁盘输出到磁盘。

线程共享一个地址空间,由于锁争用而导致许多活动导致收益递减。因此在数据库的情况下,许多进程读取表可以同时进行,但依赖数据的更新需要序列化以保持数据一致,这可能导致锁争用并限制并行处理。

写得不好的查询需要加载&将大表分类到内存中,当它们超过空闲RAM时可能会导致颠簸(可能选择不当的索引)。您可以通过使用大型RAM磁盘缓存并使用SSD来减少随机数据访问时间来提高查询吞吐量,更多地利用CPU。

在内存密集型计算中,缓存大小可能变得很重要,数据保留在缓存中的线程越少,CPU预取最小化停顿,比竞争从主内存加载数据的线程更好。