JVM在多核上的表现

8

有相当多有关 Java、性能和多核 的有前途的链接。如果这篇博客文章在列表中,请留言告诉我。 - Andreas Dolk
10个回答

8

如果不同线程之间的共享资源存在显著争用,那么锁定和解锁对象可能需要大量的IPI(处理器间中断),处理器可能会花费更多时间丢弃其L1和L2缓存并从其他CPU重新获取数据,而不是实际上在解决手头问题上取得进展。

如果应用程序具有过于细粒度的锁定,则可能会出现问题。 (我曾经听说过这样的总结:“每个CPU缓存行只需要一个锁”,这确实是正确的,但可能仍然过于细粒度。)

Java的“每个对象都是互斥锁”可能会导致在运行系统中有太多锁定,如果太多锁定存在且争用,则会出现问题。

我毫不怀疑有人可能会故意编写这样的应用程序,但这可能并不常见。 大多数开发人员会编写他们的应用程序以尽可能减少资源争用。


这忽略了Amdahl定律Little定理,它们基本上可以归结为:有些事情无论使用什么编程语言/环境,都不能很好地分割成并行任务。 - Nitsan Wakart

1

我对 "Much" 部分表示怀疑。

我的猜测是,将状态从一个 CPU 移动到另一个 CPU 的成本足够高,以至于会引起注意。通常,您希望作业留在同一 CPU 上,这样它的数据可以尽可能地本地缓存。


1

这完全是猜测,没有相关的文章/数据,但有些类型的程序不适合并行化 - 也许应用程序从未受到 CPU 的限制(意味着 CPU 不是瓶颈,可能是某种 I/O)。

然而,如果没有更多细节,这个问题/对话就毫无意义。


1

这并非是Java特有的原因,但将状态从核心移动到核心甚至从CPU移动到CPU都需要时间。如果进程保持在单个核心上,则可以更好地利用此时间。此外,在这种情况下,缓存也可以得到改善。

然而,仅当程序不使用多个线程并且能够有效地将其工作分配到多个核心/ CPU时,才具有相关性。


1

该应用程序可能会非常糟糕地使用阻塞的线程间通信。然而,这纯粹是因为该应用程序编程异常糟糕。

没有任何理由使得任何一个即使是中等水平编程的多核应用程序在具有适度可并行工作负载的情况下在多个核心上运行更慢。


1

从纯性能角度来看,挑战通常在于内存子系统。因此,虽然更多的 CPU 通常是好的,但是拥有不靠近 Java 对象所在内存的 CPU 是非常昂贵的。这非常依赖于每个 CPU 和内存之间的确切路径,因此非常机器特定。英特尔和 AMD 在这方面有各种形状/速度,结果差异很大。

请参见 NUMA 以了解多核可能会妨碍的原因。

我们已经看到性能差距在30%左右,具体取决于 JVM 如何固定到处理器上。出于这个原因,SPECjbb2005 现在主要在“多 JVM”模式下运行,每个 JVM 关联一个给定的 CPU / 内存。


1

JIT(即时编译器)如果认为它在单核上运行,将不包括内存屏障。我怀疑这就是所引用文章中发生的情况。

以下是内存屏障的非常简明的解释,它还提供了一种巧妙的技术来查看JIT编译的代码: http://www.infoq.com/articles/memory_barriers_jvm_concurrency

这并不意味着所有应用程序都会从放置在单个核心上中受益。


0

最糟糕的情况是,一个真正荒谬(甚至恶意)的任务调度器可能会尝试安排事情,以便Turbo Boost不会启动——我甚至不确定它是否可以被操纵。无论如何,它永远不会产生6倍的性能差异。 - Nicholas Knight
1
我同意。Turbo Boost 甚至无法接近 6 倍的性能提升。 - Puppy

0
这将取决于应用程序生成的线程数量。如果您生成了四个执行大量数字计算的工作线程,那么在四核机器上,应用程序的速度将快近四倍,具体取决于您需要进行多少簿记和合并操作。

0

CPU通常有产生多少热量的限制。这意味着具有较少内核的芯片可以以高频率运行,如果程序没有有效地使用额外的内核,则可以导致程序运行更快。今天,4、6和8个内核之间的差异在于,更多的内核单独运行速度较慢。我不知道是否有任何单核系统比最快的4核系统更快。


在这篇文章中,作者通过将服务器分配给单个CPU而不是6个来使其更快。 - IttayD
你说得对,他把所有的进程都分配到了一个核心。如果这样做可以工作,那么他几乎肯定存在调整问题,但具体是什么还不清楚。 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接