Lookup Op производительность - PullRequest
       10

Lookup Op производительность

1 голос
/ 05 ноября 2008

Я пытаюсь увеличить производительность моего конвейера рендеринга. (Безусловно) самая медленная часть выполняет java.awt.imaging.LookupOp на большом изображении.

Размер изображения составляет около 2048x2048.

Я понял, что выполнение фильтра вместе с операцией рисования намного быстрее, чем вызов метода фильтра. Однако это все еще оставляет нас с операциями поиска, которые занимают приблизительно 250 мс (или 4 кадра в секунду). У кого-нибудь есть какие-нибудь советы по рендерингу?

Вот по сути то, что мы делаем:

public void paint(Graphics g)
{
    if(recalcLUT)
    {
        Graphics2D g2d = (Graphics2D) displayImage.getGraphics();
        g2d.drawImage(srcImage, lut, 0, 0);
    }

    Graphics2D g2d = (Graphics2D) g;
    g2d.clearRect(0, 0, this.getWidth(), this.getHeight());
    AffineTransform at = new AffineTransform();
    at.setToIdentity();
    at.scale(scale, scale);
    g2d.drawImage(displayImage, at, null);
}

переменная lut - это LookupOp, обычно ShortLookupOp, изображение - 16-битное изображение в градациях серого

Спасибо

Райан Бухер:

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

Lookup Ops - это, по сути, место, где вы создаете массив, и вместо того, чтобы отображать каждый пиксель изображения в качестве его цвета, вы используете цвет как индекс в массиве и визуализируете цвет как значение в индексе. В этом конкретном примере я использую его для выполнения некоторых простых операций яркости / контраста. Вы также можете реализовать это, используя rescaleOp, который по сути является способом применения линейной функции к значению всех пикселей. Но это оказывается медленнее.

Ответы [ 2 ]

1 голос
/ 07 ноября 2008

Я не использовал java около восьми лет, поэтому некоторые синтаксисы могут не иметь значения.

Ключом к любому виду производительности в отношении цикла является выталкивание как можно большего количества вещей из цикла. Если вы не можете тогда выполнять вычисления, только когда они меняются. Часто лучше подождать до последней минуты для пересчета, чтобы можно было кэшировать несколько изменений.

  1. Переместите всю конструкцию объекта за пределы цикла рендеринга. Если вы знаете, сколько объектов вам нужно заранее, то передайте их; если вы не используете пул объектов и фабрика создает объекты за пределами renderloop. Это сэкономит вам время строительства / разрушения.

  2. Рассчитайте свой AffineTransform только при изменении масштаба. Выдвиньте это за пределы цикла рисования и передайте его (как константную ссылку ... они вообще существуют в Java? Я был в C ++ слишком долго)

  3. Вам может не понадобиться вызывать at.setToIdentity (), поскольку ваш AffineTransform должен по умолчанию использовать матрицу Identity (отметьте это)

  4. Нужно ли вызывать recalcLUT каждый кадр? Имеет ли смысл устанавливать recalcLUT в false после выполнения оператора if?

Я не уверен, какова цель LookupOp. Если вы дадите мне немного больше информации о том, что он делает, я могу предложить больше.

Надеюсь, это поможет.

0 голосов
/ 07 ноября 2008

У вас есть возможность перенести эту обработку на графический процессор? Несколько аппаратных конвейеров значительно ускорят обработку.

Если вы не можете, то вам следует рассмотреть распараллеливание LookupOp на CPU. Из того, что я понимаю, каждый поиск может быть сделан в изоляции. Таким образом, вы можете раскрутить несколько потоков (сколько зависит от вашего CPU Arch и всего, что происходит одновременно), и каждый поток просматривает часть изображения. Вам понадобится семафор при каждом запуске обновления, чтобы дождаться завершения всех потоков.

В любом случае вы должны сделать следующее, чтобы компенсировать некоторое потребление памяти для каждого кадра, в котором нет изменений. Если ваша частота кадров не ограничена, то чем больше у вас кадров, тем больше шансов, что ничего не изменилось. Это избавит вас от ненужной работы.

//Has filter or source image changed?
//   yes, recalculate filter and cache
//   no, render cached image

Наконец, есть ли у вас представление о реализации LookupOp? Что он делает, есть ли какие-либо улучшения производительности, которые можно почерпнуть, написав реализацию самостоятельно (это должно быть последнее средство).

...