Що викликає розгалуження в GLSL, залежить від моделі GPU та версії драйвера OpenGL.
Здається, більшість графічних процесорів мають форму операції "вибрати одне з двох значень", яка не має вартості розгалуження:
n = (a==b) ? x : y;
а іноді навіть такі речі, як:
if(a==b) {
n = x;
m = y;
} else {
n = y;
m = x;
}
буде зменшено до декількох операцій із вибраним значенням без штрафного розгалуження.
Деякі графічні процесори / драйвери мають (мали?) Трохи штрафу для оператора порівняння між двома значеннями, але більш швидкої роботи порівняння проти нуля.
Де це можна зробити швидше:
gl_FragColor.xyz = ((tmp1 - tmp2) != vec3(0.0)) ? E : tmp1;
замість того, щоб (tmp1 != tmp2)
безпосередньо порівнювати, але це дуже залежить від GPU та драйвера, якщо ви не орієнтуєтесь на дуже конкретний GPU і ніхто інший, я рекомендую використовувати операцію порівняння і залишити цю оптимізацію завдання драйверу OpenGL, оскільки інший драйвер може мати проблеми з довшою формою і бути швидшим простішим, читабельнішим способом.
"Гілки" теж не завжди є поганою справою. Наприклад, на графічному процесорі SGX530, який використовується в OpenPandora, цей шейдер масштабу в два рази (30 мс):
lowp vec3 E = texture2D(s_texture0, v_texCoord[0]).xyz;
lowp vec3 D = texture2D(s_texture0, v_texCoord[1]).xyz;
lowp vec3 F = texture2D(s_texture0, v_texCoord[2]).xyz;
lowp vec3 H = texture2D(s_texture0, v_texCoord[3]).xyz;
lowp vec3 B = texture2D(s_texture0, v_texCoord[4]).xyz;
if ((D - F) * (H - B) == vec3(0.0)) {
gl_FragColor.xyz = E;
} else {
lowp vec2 p = fract(pos);
lowp vec3 tmp1 = p.x < 0.5 ? D : F;
lowp vec3 tmp2 = p.y < 0.5 ? H : B;
gl_FragColor.xyz = ((tmp1 - tmp2) != vec3(0.0)) ? E : tmp1;
}
Закінчилося значно швидше, ніж цей еквівалентний шейдер (80 мс):
lowp vec3 E = texture2D(s_texture0, v_texCoord[0]).xyz;
lowp vec3 D = texture2D(s_texture0, v_texCoord[1]).xyz;
lowp vec3 F = texture2D(s_texture0, v_texCoord[2]).xyz;
lowp vec3 H = texture2D(s_texture0, v_texCoord[3]).xyz;
lowp vec3 B = texture2D(s_texture0, v_texCoord[4]).xyz;
lowp vec2 p = fract(pos);
lowp vec3 tmp1 = p.x < 0.5 ? D : F;
lowp vec3 tmp2 = p.y < 0.5 ? H : B;
lowp vec3 tmp3 = D == F || H == B ? E : tmp1;
gl_FragColor.xyz = tmp1 == tmp2 ? tmp3 : E;
Ви ніколи не знаєте заздалегідь, як буде працювати конкретний компілятор GLSL або конкретний графічний процесор, поки ви не порівняєте його.
Щоб додати точку (навіть у тому, що я не маю фактичних номерів хронометражу та шейдерного коду, щоб представити вас для цієї частини), я в даний час використовую як моє звичайне обладнання для тестування:
- Intel HD Graphics 3000
- Графіка Intel HD 405
- nVidia GTX 560M
- nVidia GTX 960
- AMD Radeon R7 260X
- nVidia GTX 1050
Як широкий спектр різних, поширених, GPU моделей, з якими можна перевірити.
Тестування кожного за допомогою власників Windows, Linux та Linux з відкритим кодом OpenGL та OpenCL.
І кожен раз, коли я намагаюся мікро-оптимізувати шейдер GLSL (як у прикладі SGX530 вище) або операції OpenCL для одного конкретного комбінованого GPU / драйвера, я в кінцевому підсумку пошкоджую продуктивність на більш ніж одному з інших графічних процесорів / драйверів.
Отже, крім чіткого зменшення математичної складності високого рівня (наприклад: конвертувати 5 однакових поділів на один зворотний і замість цього 5 розмножень) та зменшення пошуку тексту / пропускної здатності текстури, швидше за все, це буде марною тратою вашого часу.
Кожен графічний процесор занадто відрізняється від інших.
Якщо ви працюєте спеціально над (а) ігровими консолями (-ми) з певним графічним процесором, це була б інша історія.
Інший (менш важливий для невеликих розробників ігор, але все-таки помітний) полягає в тому, що драйвери комп'ютерних графічних процесорів можуть одного дня мовчки замінити ваші шейдери ( якщо ваша гра стане досить популярною ) на власні переписані, оптимізовані для цього конкретного GPU. Це все для вас працює.
Вони будуть робити це для популярних ігор, які часто використовуються як орієнтири.
Або якщо ви надаєте гравцям доступ до шейдерів, щоб вони могли легко їх редагувати, деякі з них можуть видавити кілька додаткових FPS для власної вигоди.
Наприклад, існують фан-шейдери та фактурні пакети для Oblivion, щоб різко збільшити частоту кадрів на іншому ледь відтворюваному обладнання.
І нарешті, як тільки ваш шейдер набереться досить складно, ваша гра майже завершена, і ви почнете тестувати на іншому апаратному забезпеченні, ви будете достатньо зайняті просто виправленням ваших шейдерів, щоб взагалі працювати на різних графічних процесорах, оскільки це пов'язано з різними помилками, які ви не мали встигнути оптимізувати їх до такої міри.