在我运行的每一个测试中,函数调用都有大量的开销。代码是一个紧密的循环,对数组的每个元素(包含4-8百万ints)执行一个非常简单的函数。
运行代码,主要由以下内容组成:
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;
};在各种机器上(我的工作笔记本电脑、带有W530 3840 VM的i7、具有XeonE5-1620内核的服务器VM和具有一个未知CPU核心的数字海洋节点),在调用方法和内联时,我反复得到了显著的性能影响。所有测试都是在Java 1.8.0_11 ( 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专用服务器,VM:
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做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倍的性能提升,这可能是值得的,但维护将是一场噩梦。
我不确定是否有一种合理的方法来批量处理一组重复;大多数操作都需要多个输入(调用者不知道)并产生一个输出。
我还有什么其他的选择来最小化开销和晚上的性能呢?
发布于 2014-07-21 21:40:43
方法调用不是问题,因为热门方法通常是内联的。虚拟调用是一个问题。
在您的代码中,类型分析器被初始化方法Image.random所愚弄。当Image.process第一次被JIT编译时,它被优化为调用random.nextInt()。因此,下一次对Image.process的调用将导致内联缓存丢失,然后是对Shader.apply的非优化虚拟调用。
Image.process调用,然后JIT将内联对Shader.apply的有用调用。BlurShader.apply内联之后,您可以通过替换
最后整数p=s*y+ x;
使用
最后整数p=y*s+ x;
在Image.process中也会遇到后一个表达式,因此JIT不会计算相同的表达式两次。在应用这两项更改之后,我达到了理想的基准得分:
Benchmark Mode Samples Mean Mean error Units
s.ShaderBench.testProcessInline thrpt 5 36,483 1,255 ops/s
s.ShaderBench.testProcessLambda thrpt 5 36,323 0,936 ops/s
s.ShaderBench.testProcessProc thrpt 5 36,163 1,421 ops/shttps://stackoverflow.com/questions/24873010
复制相似问题