I have 一段代码在我运行的每个测试中,函数调用都会产生大量开销。该代码是一个紧密循环,对数组(包含 4-800 万个元素)的每个元素执行一个非常简单的函数int
s).
运行代码,主要包括
for (int y = 1; y < h; ++y) {
for (int x = 1; x < w; ++x) {
final int p = y * s + x;
n[p] = f.apply(d, s, x, y);
}
}
执行类似的事情
(final int[] d, final int s, final int x, final int y) -> {
final int p = s * y + x;
final int a = d[p] * 2
+ d[p - 1]
+ d[p + 1]
+ d[p - s]
+ d[p + s];
return (1000 * (a + 500)) / 6000;
};
在各种机器上(我的工作笔记本电脑、配备 i7 3840QM 的 W530、配备一个 Xeon E5-1620 核心的服务器虚拟机,以及配备一个未知 CPU 核心的 Digital Ocean 节点),当我调用方法与内联。所有测试均在 Java 1.8.0_11(Java HotSpot(TM) 64 位服务器 VM)上执行。
工作机:
Benchmark Mode Samples Score Score error Units
c.s.q.ShaderBench.testProcessInline thrpt 200 40.860 0.184 ops/s
c.s.q.ShaderBench.testProcessLambda thrpt 200 22.603 0.159 ops/s
c.s.q.ShaderBench.testProcessProc thrpt 200 22.792 0.117 ops/s
专用服务器、虚拟机:
Benchmark Mode Samples Score Score error Units
c.s.q.ShaderBench.testProcessInline thrpt 200 40.685 0.224 ops/s
c.s.q.ShaderBench.testProcessLambda thrpt 200 16.077 0.113 ops/s
c.s.q.ShaderBench.testProcessProc thrpt 200 23.827 0.088 ops/s
DO VPS:
Benchmark Mode Samples Score Score error Units
c.s.q.ShaderBench.testProcessInline thrpt 200 24.425 0.506 ops/s
c.s.q.ShaderBench.testProcessLambda thrpt 200 9.643 0.140 ops/s
c.s.q.ShaderBench.testProcessProc thrpt 200 13.733 0.134 ops/s
所有性能都可以接受,但我有兴趣弄清楚为什么调用有如此大的开销以及可以采取哪些措施来优化它。目前正在尝试不同的参数集。
内联所有潜在的操作会很困难,但理论上是可能的。对于接近 2 倍的性能提升来说,这可能是值得的,但维护将是一场噩梦。
我不确定是否有合理的方法来批量处理一组重复;大多数操作采用多个输入(调用者未知)并产生单个输出。
我还有哪些其他选择可以最大限度地减少开销并提高晚上的性能?