如果不同线程之间的共享资源存在显著争用,那么锁定和解锁对象可能需要大量的IPI(处理器间中断),处理器可能会花费更多时间丢弃其L1和L2缓存并从其他CPU重新获取数据,而不是实际上在解决手头问题上取得进展。
如果应用程序具有过于细粒度的锁定,则可能会出现问题。 (我曾经听说过这样的总结:“每个CPU缓存行只需要一个锁”,这确实是正确的,但可能仍然过于细粒度。)
Java的“每个对象都是互斥锁”可能会导致在运行系统中有太多锁定,如果太多锁定存在且争用,则会出现问题。
我毫不怀疑有人可能会故意编写这样的应用程序,但这可能并不常见。 大多数开发人员会编写他们的应用程序以尽可能减少资源争用。
我对 "Much" 部分表示怀疑。
我的猜测是,将状态从一个 CPU 移动到另一个 CPU 的成本足够高,以至于会引起注意。通常,您希望作业留在同一 CPU 上,这样它的数据可以尽可能地本地缓存。
这完全是猜测,没有相关的文章/数据,但有些类型的程序不适合并行化 - 也许应用程序从未受到 CPU 的限制(意味着 CPU 不是瓶颈,可能是某种 I/O)。
然而,如果没有更多细节,这个问题/对话就毫无意义。
这并非是Java特有的原因,但将状态从核心移动到核心甚至从CPU移动到CPU都需要时间。如果进程保持在单个核心上,则可以更好地利用此时间。此外,在这种情况下,缓存也可以得到改善。
然而,仅当程序不使用多个线程并且能够有效地将其工作分配到多个核心/ CPU时,才具有相关性。
该应用程序可能会非常糟糕地使用阻塞的线程间通信。然而,这纯粹是因为该应用程序编程异常糟糕。
没有任何理由使得任何一个即使是中等水平编程的多核应用程序在具有适度可并行工作负载的情况下在多个核心上运行更慢。
从纯性能角度来看,挑战通常在于内存子系统。因此,虽然更多的 CPU 通常是好的,但是拥有不靠近 Java 对象所在内存的 CPU 是非常昂贵的。这非常依赖于每个 CPU 和内存之间的确切路径,因此非常机器特定。英特尔和 AMD 在这方面有各种形状/速度,结果差异很大。
请参见 NUMA 以了解多核可能会妨碍的原因。
我们已经看到性能差距在30%左右,具体取决于 JVM 如何固定到处理器上。出于这个原因,SPECjbb2005 现在主要在“多 JVM”模式下运行,每个 JVM 关联一个给定的 CPU / 内存。
JIT(即时编译器)如果认为它在单核上运行,将不包括内存屏障。我怀疑这就是所引用文章中发生的情况。
以下是内存屏障的非常简明的解释,它还提供了一种巧妙的技术来查看JIT编译的代码: http://www.infoq.com/articles/memory_barriers_jvm_concurrency
这并不意味着所有应用程序都会从放置在单个核心上中受益。
近期的英特尔 CPU 均有 Turbo Boost 功能:
CPU通常有产生多少热量的限制。这意味着具有较少内核的芯片可以以高频率运行,如果程序没有有效地使用额外的内核,则可以导致程序运行更快。今天,4、6和8个内核之间的差异在于,更多的内核单独运行速度较慢。我不知道是否有任何单核系统比最快的4核系统更快。