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