Я разрабатываю симуляцию на основе GPU с использованием OpenGL и GLSL-Shaders, и я обнаружил, что производительность увеличивается, когда я добавляю дополнительные (ненужные) GL-команды.Runtime моделирования на основе GPU необъяснимо?
Моделирование выполняется полностью на графическом процессоре без каких-либо переводов и в основном состоит из цикла, выполняющего алгоритмически идентичные по времени 2500 шагов. Я тщательно реализовал кеширование однотипных местоположений GLSL и удалил любые запросы GL-состояния (glGet * и т. Д.), Чтобы максимизировать скорость. Чтобы измерить время настенных часов, я поместил glFinish
после основного цикла и через некоторое время истек.
СЛУЧАЙ A: Нормальное общее время выполнения всех итераций 490ms.
СЛУЧАЙ B: Теперь, если я добавить один дополнительный glGetUniformLocation(...)
команду в конце каждого временного шага, он требует только 475ms в целом, что 3 процента быстрее. (Обратите внимание, что это относится ко мне, так как позже я буду выполнять намного больше времени)
Я просмотрел временную шкалу, зафиксированную Nvidia nsight, и обнаружил, что в случае A все команды opengl выдаются в течение первого 140 мс, а glFinish занимает 348 мс до завершения всего GPU-работы. В случае, если выдача команд opengl распространяется на значительно более длительное время (410 мс), а glFinish занимает всего 64 мс, что дает более быстрые 475 мс.
Я также заметил, что очередь командных команд больше времени заполняется рабочими пакетами большую часть времени в случае B, тогда как в случае, когда A остается только один элемент, ожидающий большую часть времени (однако, нет видимых простоя).
Так что мои вопросы:
- Почему B быстрее?
- Почему пакеты команд выпущены более равномерно для очереди оборудования в течение времени в случае A?
- Как повысить скорость без добавления дополнительных команд?
Я использую Visual C++, VS2008 на Win7 x64.
Сигнальный шум? 3 процента по всему кадру немного малы. –
Это будет самый воспроизводимый шум когда-либо;) Процесс имеет высокий приоритет, одно ядро, и результаты могут быть воспроизведены с помощью 50 000 шагов времени. Также стандартное отклонение в обоих случаях составляет менее 2 мс. – Thomas
glGetUniformLocation закроет трубопровод. Именно по этой причине вызов glFinish выполняется быстрее в B. В glFinish ожидает, пока все команды opengl, ранее выпущенные, закончены, а в B glGetUniformLocation выполнит ожидание. – BDL