【发布时间】:2013-11-08 21:11:23
【问题描述】:
我使用 JOGL 在 Java 中编写了一个 OpenGL 应用程序。我试图完全避免在主应用程序阶段创建对象,因为它可能会导致 GC 引起的小周期性延迟。
我想用我自己的包装一些 JOGL 的方法。想象一个方法
void method(int[] result, int offset),它接收指向数组的指针和偏移量,并在指定索引处将一个整数值放入其中。我想用简单的int getResult()包装它所以我需要在某个地方创建一个临时数组,而且我必须提前做(根据1)。
但是如果它将存储在包含此包装方法的类的字段中,这将迫使我制作包装方法
synchronized。我知道大部分单线程访问的时间同步不应该产生很大的开销,但我仍然想知道是否有更好的解决方案。
注意事项:
- 同步不是答案,3.000.000 个 empty 同步块,只是 monitorenter-monitorexit 需要 17 毫秒。如果你想保持 60 fps,你只有 16.(6)。
由于我没有足够的权力来投票,我发现欣赏 Dave 答案的唯一方法是编写一个演示:
class Test {
private static final int CYCLES = 1000000000;
int[] global = new int[1];
ThreadLocal<int[]> local = new ThreadLocal<int[]>();
void _fastButIncorrect() { global[0] = 1; }
synchronized void _slowButCorrect() { global[0] = 1; }
void _amazing() {
int[] tmp = local.get();
if( tmp == null ){
tmp = new int[1];
local.set(tmp);
}
tmp[0] = 1;
}
long fastButIncorrect() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _fastButIncorrect();
return System.currentTimeMillis() - l;
}
long slowButCorrect() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _slowButCorrect();
return System.currentTimeMillis() - l;
}
long amazing() {
long l = System.currentTimeMillis();
for (int i = 0; i < CYCLES; i++) _amazing();
return System.currentTimeMillis() - l;
}
void test() {
System.out.println(
"fastButIncorrect cold: " + fastButIncorrect() + "\n" +
"slowButCorrect cold: " + slowButCorrect() + "\n" +
"amazing cold: " + amazing() + "\n" +
"fastButIncorrect hot: " + fastButIncorrect() + "\n" +
"slowButCorrect hot: " + slowButCorrect() + "\n" +
"amazing hot: " + amazing() + "\n"
);
}
public static void main(String[] args) {
new Test().test();
}
}
在我的机器上结果是:
fastButIncorrect cold: 40
slowButCorrect cold: 8871
amazing cold: 46
fastButIncorrect hot: 38
slowButCorrect hot: 9165
amazing hot: 41
再次感谢戴夫!
【问题讨论】:
-
1.听起来像一个严重过早的担忧。
-
@MattBall 的评论很到位。您是否有显示 GC 滞后的分析器输出?除非您有相当水平的对象带宽,否则这应该不是问题。
-
请避免讨论问题的性质。没有同步且不创建对象的解决方案吗?
-
为什么不为每个线程创建一个包装器?这是一个问题——渲染本身是多线程的吗? Jogl 是否完全支持这一点?
-
@StefanHaustein 也许这是最好的解决方案,但它会稍微改变架构。
标签: java performance concurrency logic