Влияние петель переменной длины на шейдеры GPU

9

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

Лучевой марш популярен:

введите описание изображения здесь

Это означает, что графический процессор выполняет некоторое неизвестное число итераций цикла на пиксель (хотя вы можете иметь верхнюю границу, например maxIterations).

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

Представьте себе простой маршевый псевдокод:

t = 0.f;
while(t < maxDist) {
    p = rayStart + rayDir * t;
    d = DistanceFunc(p);
    t += d;
    if(d < epsilon) {
       ... emit p
       return;
    }
}

Как влияют различные семейства графических процессоров (Nvidia, ATI, PowerVR, Mali, Intel и т. Д.)? Вершинные шейдеры, но особенно фрагментные шейдеры?

Как это можно оптимизировать?

Будет
источник
К сожалению, здесь слишком сложно ответить на этот вопрос. Хотя один ответ уже дал указание на такой источник, который стоит прочитать (подразумевает динамическое ветвление). +1 за «тему» ​​..
Теодрон
1
@ Теодрон не будь пораженцем! Я надеялся, что кто-то скажет, что на картах NVidia пиксели экрана в блоках 8x8 будут повторяться настолько глубоко, насколько это необходимо, и что блоки 8x8 пикселей могут быть выполнены в любом порядке или что-то в этом роде; это не правда, это просто та мудрость, я надеюсь, что люди смогут поделиться. Ссылки на Larrabee, хм, довольно косвенные.
Будет
Не похоже, что он обсуждает Ларраби, но парень из Стэнфорда выступил с такой же речью два года спустя, в 2010 году ( вы можете увидеть это здесь ). Из его рисунков, учитывая цикл while, я не понял, компенсируют ли пиксели, которые «заканчивают» свои вычисления раньше, какую-либо производительность. В CUDA потоки ожидают барьера. По аналогии, что происходит с шейдерными потоками?
Теодрон
@teodron да, я понял, что такое CUDA, и обратился к графическим процессорам; Я уверен, что они находятся на пороге, но я хотел бы, чтобы кто-то знающий вмешался; во всяком случае, вот что-то связанное williamedwardscoder.tumblr.com/post/26628848007/rod-marching
Уилл

Ответы:

8

На GDC 2012 было приятно поговорить о дистанционном полевом поле GPU (и других темах): http://directtovideo.wordpress.com/2012/03/15/get-my-slides-from-gdc2012/

Что касается производительности, то новейшие видеокарты (класса DX11) выполняют шейдеры на SIMD-блоках, в которых 32 (NVIDIA) или 64 (AMD) «потока» находятся в режиме ожидания. Эти группы по-разному известны как деформации или волновые фронты. Для пиксельных шейдеров каждый поток равен одному пикселю, поэтому я ожидаю, что модуль SIMD обрабатывает что-то вроде блока пикселей 8x4 (NVIDIA) или 8x8 (AMD) вместе. Ветвление и управление потоком выполняются для каждого волнового фронта, поэтому все потоки в волновом фронте должны зацикливаться столько раз, сколько самый глубокий отдельный пиксель в этом волновом фронте. Маски линий SIMD отключат выполнение для уже законченных пикселей, но им все равно придется молча согласиться с управлением потоком всего волнового фронта. Это означает, конечно, что система намного более эффективна, когда ветвление является последовательным,

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

Натан Рид
источник
0

Что касается динамического ветвления, еще одно замечание (может быть очевидным, но все же стоит обратить внимание на некоторых людей): оно может серьезно повлиять на производительность развернутых циклов (очевидно, что вы не можете развернуть цикл, если существует непостоянное число итераций) ,

Гаван Вулери
источник
-4

int s = 0;

теперь для (int k = 1; k <= n; k ++) {s + = k;} то же самое, что s = n * (n + 1) / 2

так что это не так в целом: D

канитель
источник
1
Возможно, вам часто отказывают в голосовании, потому что никто не совсем уверен, что вы пытаетесь передать здесь или как это связано с вопросом.
двойник