除了互斥锁或垃圾回收之外,还有哪些机制会减慢我的多线程 Java 程序的速度?
问题
我有一段java代码(JDK 1.6.0._22,如果相关的话),它实现了一个无状态的,没有副作用的函数,没有互斥锁。然而,它确实使用了大量的内存(我不知道这是否相关)。
过去,我访问过太阳实验室,并收集了标准的“性能与线程数”曲线。由于此函数没有互斥锁,因此它有一个很好的图形,尽管随着线程数量的增加,垃圾回收开始发挥作用。经过一些垃圾回收调整,我能够使这条曲线几乎平坦。
我现在在英特尔硬件上做同样的实验。硬件有 4 个 CPU,每个 CPU 有 8 个内核,以及超线程。这给出了64个可用的处理器()。不幸的是,“性能与线程数”的曲线可以很好地缩放1,2,3个线程,上限为3个线程。经过3个线程后,我可以根据需要将任意数量的线程放入任务中,并且性能不会更好
尝试解决问题
我的第一个想法是,我一直很愚蠢,在某个地方引入了一些同步代码。通常,为了解决这个问题,我运行JConsole或JVisualVM,并查看线程堆栈跟踪。如果我有 64 个线程以 3 的速度运行,我预计其中 61 个线程会坐着等待进入互斥体。我没有找到这个。相反,我发现所有的线程都在运行:只是非常慢。
第二个想法是,也许时间框架带来了问题。我用一个虚拟函数替换了我的函数,这个函数使用AtomicLong只能算作十亿。这随着线程数量的增加而完美地扩展:我能够数到10亿倍,64个线程比1个线程快64倍。
我想(绝望开始了)也许垃圾回收需要很长时间,所以我调整了垃圾回收参数。虽然这改善了我的延迟变化,但它对吞吐量没有影响:我仍然有64个线程以我期望3运行的速度运行。
我已经下载了英特尔工具VTunes,但我的技能很弱:它是一个复杂的工具,我还不了解它。我订购了说明书:给自己一个有趣的圣诞礼物,但这有点太晚了,无法帮助我目前的问题
问题
- 我可以使用哪些工具(心理或软件)来提高我对正在发生的事情的理解?
- 除了互斥锁或垃圾回收之外,还有哪些机制可能会减慢我的代码速度?