Как максимально использовать SIMD в OpenCL?

В руководстве по оптимизации Beignet, реализации OpenCL с открытым исходным кодом для графических процессоров Intel

Размер рабочей группы должен быть больше 16 и быть кратным 16.

Поскольку две возможные полосы SIMD в Gen — это 8 или 16. Чтобы не тратить дорожки SIMD впустую, нам нужно следовать этому правилу.

Также упоминается в вычислительных Архитектура процессорной графики Intel Gen7.5:

Для продуктов на основе Gen7.5 каждый EU имеет семь потоков, что в сумме составляет 28 Кбайт файла регистров общего назначения (GRF).

...

В вычислительной архитектуре Gen7.5 большинство моделей программирования SPMD используют генерацию кода в этом стиле и выполнение процессора EU. По сути, каждый экземпляр ядра SPMD выполняется последовательно и независимо в пределах своей собственной дорожки SIMD.

На самом деле, каждый поток одновременно выполняет количество экземпляров ядра, равное числу SIMD-Width. Таким образом, для компиляции SIMD-16 вычислительного ядра возможно, чтобы SIMD-16 x 7 потоков = 112 экземпляров ядра выполнялись одновременно на одном EU. Аналогично, для SIMD-32 x 7 потоков = 224 экземпляра ядра, выполняющихся одновременно в одном EU.

Если я правильно понимаю, используя SIMD-16 x 7 threads = 112 kernel instances в качестве примера, чтобы запустить 224 потока на одном EU, размер рабочей группы должен быть 16. Тогда компилятор OpenCL свернет 16 экземпляров ядра в 16-полосный поток SIMD и сделает это 7 раз по 7 рабочим группам и запускать их на одном ЕС?

Вопрос 1: прав ли я до сих пор?

Однако спецификация OpenCL также предоставляет векторные типы данных. Таким образом, можно полностью использовать вычислительные ресурсы SIMD-16 в ЕС с помощью обычного программирования SIMD (как в NEON и SSE).

Вопрос 2. Если это так, использование типа данных vector-16 уже явно использует ресурсы SIMD-16 и, следовательно, снимает ограничение не менее 16 элементов на рабочую группу. . Так ли это?

Вопрос 3: Если все вышеперечисленное верно, то как эти два подхода соотносятся друг с другом: 1) 112 потоков объединяются в 7 потоков SIMD-16 компилятором OpenCL; 2) 7 собственных потоков, закодированных для явного использования типов данных vector-16 и операций SIMD-16?


person user3528438    schedule 31.10.2015    source источник


Ответы (1)


  1. Почти. Вы делаете предположения, что в каждой рабочей группе есть один поток (N.B. поток в этом контексте - это то, что CUDA называет "волной". В графическом процессоре Intel говорят, что рабочий элемент - это SIMD-канал потока графического процессора). Без подгрупп невозможно заставить размер рабочей группы точно соответствовать потоку. Например, если вы выберете размер рабочей группы 16, компилятор по-прежнему может скомпилировать SIMD8 и распределить его между двумя потоками SIMD8. Имейте в виду, что компилятор выбирает ширину SIMD до того, как ему станет известен размер WG (clCompileProgram предшествует clEnqueueNDRange). расширение подгрупп может позволить вам задать ширину SIMD, но определенно не реализован на GEN7.5.

  2. Векторные типы OpenCL — это необязательный шаг явной векторизации поверх неявной векторизации, которая уже выполняется автоматически. Если бы вы использовали float16, например. Каждый из рабочих элементов будет обрабатывать по 16 чисел с плавающей запятой, но компилятор все равно будет компилировать как минимум SIMD8. Следовательно, каждый поток графического процессора будет обрабатывать (8 * 16) поплавков (хотя и параллельно). Это может быть немного лишним. В идеале мы не хотим явно векторизовать наш CL, используя явные векторные типы OpenCL. Но иногда это может быть полезно, если ядро ​​выполняет недостаточно работы (слишком короткие ядра могут быть плохими). Где-то говорится, что float4 - хорошее эмпирическое правило.

  3. Я думаю, вы имели в виду 112 рабочих элементов? Под собственным потоком вы подразумеваете потоки ЦП или потоки графического процессора?

    • If you meant CPU threads, the usual arguments about GPUs apply. GPUs are good when your program doesn't diverge much (all instances take similar paths) and you use the data enough times to mitigate the cost transferring it to and from the GPU (arithmetic density).
    • Если вы имели в виду потоки графического процессора (твари GEN SIMD8 или SIMD16). На данный момент нет (общедоступного) способа явного программирования потоков графического процессора (EDIT см. расширение подгрупп (недоступно в GEN7.5)). Если бы вы могли, это было бы похоже на компромисс с языком ассемблера. Работа сложнее, и компилятор иногда просто справляется лучше, чем мы, но когда вы решаете конкретную проблему и лучше знаете предметную область, вы, как правило, можете добиться большего успеха при достаточном программировании (до тех пор, пока не изменится аппаратное обеспечение и предположения вашей умной программы). становится недействительным.)
person Tim    schedule 31.10.2015