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

Мне нужно измерить время вычислительного шейдера. Но, конечно, это не тривиально.
От 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 тоже, но я не уверен, как это работает, и не знаю, полезно ли мне его использовать или нет. Это новость для меня, и я не уверен, полностью ли я понимаю это сейчас.

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

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

4

Решение

Запросы по таймеру — это определенно лучший способ.

Общий принцип заключается в том, что вы создаете «объекты запроса», которые вставляете между вызовами функций 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. & Процессор для синхронизации, который замедлит работу вашего приложения (но все же даст вам хорошие временные характеристики GL), или будет иметь несколько запросов в полете.

6

Другие решения