Скорость функции cos() и sin() в шейдерах GLSL?

меня интересует информация о скорости sin() и cos() на открыть язык шейдеров GL.

на документ спецификации GLSL указано следующее:

встроенные функции, в основном, делятся на три категории:

  • ...
  • ...
  • они представляют собой графическое оборудование операции, вероятно, ускорится в какой-то момент. Тригонометрия функции попадают в это категория.

EDIT:

как было указано, подсчет тактовых циклов отдельных операций, таких как sin() и cos() не дает полной картины производительности.

поэтому, чтобы прояснить мой вопрос, что меня действительно интересует, стоит ли оптимизировать sin() и cos() вызовы для общих случаев.

например, в моем приложении это будет очень общим для аргумента 0. Так что что-то вроде этого имеет смысл:

float sina, cosa;

if ( rotation == 0 )
{
   sina = 0;
   cosa = 1;
}
else
{
   sina = sin( rotation );
   cosa = cos( rotation );
}

или GLSL компилятор или sin() и cos() реализации заботятся об оптимизации, как это для меня?

6 ответов


например, в моем приложении очень часто аргумент будет равен 0. Так что что-то вроде этого имеет смысл:

нет.

ваш компилятор сделает одну из двух вещей.

  1. он выдаст фактическую условную ветвь. В лучшем случае, если 0-это локально когерентное значение (такое, что группы шейдеров часто попадают в 0 или ненулевые вместе), то вы может получить улучшенные спектакль.
  2. он будет оценивать обеих сторон, условия, и только хранить результат для правильного одного из них. В таком случае вы ничего не выиграли.

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

кроме того, обратите внимание, что эквивалентность с плавающей запятой вряд ли будет работать. Только если ты фактически передайте шейдеру атрибут uniform или vertex, содержащий ровно 0.0. Даже интерполяция между 0 и ненулевым, вероятно, никогда не приведет к точному 0 для любого фрагмента.


Это хороший вопрос. Я тоже удивился.

ссылки Google сказать cos и sin являются одноцикловыми на основных картах с 2005 года или около того.


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

Если вы хотите взглянуть на ассемблерный код шейдера для определенной платформы, я рекомендую AMD GPU ShaderAnalyzer.


Не уверен, что это отвечает на ваш вопрос, но очень сложно сказать, сколько часов/слотов занимает инструкция, поскольку это очень зависит от GPU. Обычно это один цикл. Но даже если нет, компилятор может изменить порядок выполнения инструкций, чтобы скрыть истинную стоимость. Конечно, медленнее использовать поиск текстур для sin / cos, поскольку он должен выполнять инструкции.


посмотрите, сколько грехов вы можете получить в одном шейдере подряд, по сравнению с математикой.abs, frac, ect... я думаю, что gtx 470 может обрабатывать 200 функций sin на фрагмент без проблем, кадр будет на 10 процентов медленнее, чем пустой шейдер. это очень быстро, вы можете отправить результаты. это будет хорошим показателем эффективности вычислений.


компилятор оценивает обе ветви, что делает условия довольно дорогими. Если вы используете sin и cos в своем шейдере, вы можете вычислить только sin (a) и cos(a) = sqrt(1.0 - sin(a)), так как sin(x)*sin(x) + cos(x)*cos(x) всегда 1.0