Как измерить производительность вычислительного шейдера по времени?

мне нужно измерить время вычислительного шейдера. Но это, конечно, не мелочь. Из OpenGL Wiki - Производительность я понял, что полезно использовать glFinish() до и после вызов шейдера. Но они также говорят, что это не так хорошо, чтобы использовать его. Есть ли хорошая возможность измерить время моего шейдера? Есть ли вообще возможность измерить время вычислительного шейдера?

Мой код выглядит примерно так:

renderloop()
{
  //(1)
  //(2)
  if(updateFunction) //this is done just one time at the beginning
  {
    //update Texture with a compute shader
    //...
    glDispatchCompute();
    glMemoryBarrier(GL_ALL_BARRIER_BITS);
  }
  //(3)
  //(1)

  //use the texture to do some marching cubes rendering
}

Думаю, мне нужно вставить glFinish() в позиции (1), запустить таймер в позиции (2) и остановить его в позиции (3). Но я не уверен, что это действительно работает и даст правильные результаты синхронизации, потому что в справке они говорили о рендеринге, а вычислительный шейдер — это не рендеринг, не так ли?

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

В ответе здесь говорится, что почти невозможно точно измерить часть кода. Лучший способ — измерить время рендеринга кадра, но для моих целей мне просто нужна часть времени рендеринга кадра, связанная с вычислительным шейдером.

Как вы думаете, что является лучшей альтернативой, чтобы сделать это? Просто измерить время рендеринга всего кадра и использовать его? Или вы получили лучший опыт с другими методами измерения?


person DanceIgel    schedule 27.01.2015    source источник


Ответы (1)


Запросы таймера, безусловно, путь.

Общий принцип заключается в том, что вы создаете «объекты запроса», которые вставляете между вызовами функций GL.

Поскольку графические процессоры работают асинхронно, эти запросы будут вставлены в очередь команд графического процессора и «заполнены», когда команды действительно обрабатываются.

Итак, в вашем случае вам нужно создать запрос, используя, скажем, glGenQueries(1, &myQuery);

Затем вместо запуска таймера вы запускаете запрос в (2), используя glBeginQuery(GL_TIME_ELAPSED, myQuery), и «останавливаете» его в (3), используя glEndQuery(GL_TIME_ELAPSED).

Чтобы получить результат, вы можете просто вызвать функцию glGetQueryObject.

Вы можете узнать больше здесь, например: http://www.lighthouse3d.com/tutorials/opengl-short-tutorials/opengl-timer-query/

Конечно, есть некоторые «ловушки» - главная из них заключается в том, что вам нужно дождаться, пока результат синхронизации будет готов, поэтому вы можете синхронизировать GPU и CPU, что замедлит ваше приложение (но все же даст вам хорошие тайминги GL) или иметь несколько запросов в процессе.

person rotoglup    schedule 27.01.2015