2013-11-08 2 views
0
  1. Я пишу приложение OpenGL в Java, используя JOGL. Я пытаюсь полностью избежать создания объектов во время фазы основного приложения, так как это может привести к небольшому периодическому отставанию, вызванному GC.Как избежать синхронизации и создания объектов?

  2. Я хочу обернуть некоторые методы JOGL своим. Представьте способ void method(int[] result, int offset), который получает указатель на массив и смещение и помещает в него одно целое значение по указанному индексу. Я хочу обернуть его простым int getResult()

  3. Поэтому мне нужно создать временный массив где-нибудь, и я должен сделать это заранее (согласно 1).

  4. Но если он будет сохранен в поле класса, содержащего этот метод обертки, это заставит меня сделать метод обёртки synchronized. Я знаю, что синхронизация во времени, в основном, однопоточного доступа, не должна создавать больших накладных расходов, но я все еще хочу знать, есть ли там лучшее решение для этого.

Примечание:

  • Синхронный не является ответом, 3.000.000 из пустых синхронизированных блоков, просто monitorenter-monitorexit принять 17 мс. У вас всего 16. (6), если вы хотите сохранить 60 кадров в секунду.

Как я уже не хватает мощности для голосования до единственный способ, которым я нашел, чтобы оценить ответ Дейва сочинительство демо:

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 

Еще раз спасибо, Дэйв!

+3

1. Звучит как преждевременная озабоченность. –

+0

@ Комментарий MattBall - это место. У вас есть профайлер, который показывает задержку GC? Если у вас нет достаточного уровня пропускной способности объекта, это не должно быть проблемой. – Gray

+0

Пожалуйста, не обсуждайте характер вопроса. Разве нет решения для этого без синхронизации и без создания объекта? – Grief

ответ

4

Если вы не слишком много потоков, вы можете использовать ThreadLocal:

ThreadLocal<int[]> tmpArrayThreadLocal = new ThreadLocal<int[]>(); 

код, чтобы использовать это:

int[] tmpArray = tmpArrayThreadLocal.get(); 
if(tmpArray == null){ 
    tmpArray = new int[100]; 
    tmpArrayThreadLocal.set(tmpArray); 
} 
method(tmpArray, 5) 

Вы можете очистить код инкапсуляции ThreadLocal в другой класс.

+0

Знаете ли вы, как влияет производительность? Вам нужно будет сделать это для каждого звонка, не так ли? –

+0

Я протестировал и отлично работает!Я проверил, как они это реализуют, и кажется, что они хранят данные в самом потоке и используют фиксированное простое смещение в массиве. Так я и хотел! Большое спасибо за ответ, я играю в этот класс - никогда не слышал об этом, но он выглядит очень полезным и многообещающим. – Grief

+0

Просто будьте осторожны с количеством создаваемых вами потоков, так как эти данные не будут собирать мусор до тех пор, пока нить не закончится. – Dave

Смежные вопросы