Каков алгоритм определения оптимального размера рабочей группы и числа рабочих групп

OpenCL standard определяет следующие параметры для получения информации об устройстве и скомпилированном ядре:

  • CL_DEVICE_MAX_COMPUTE_UNITS

  • CL_DEVICE_MAX_WORK_GROUP_SIZE

  • CL_KERNEL_WORK_GROUP_SIZE

  • CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE

Учитывая эти значения, как я могу рассчитать оптимальный размер рабочей группы и количества рабочих групп?

Ответ 1

Вы обнаружите эти значения экспериментально для своего алгоритма. Используйте профилировщик для получения жестких номеров.

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

Несколько кратных CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE будут оптимальными для вашего устройства. То, что на самом деле такое множество, зависит от вашего шаблона доступа к памяти и типа работы, которую вы выполняете с каждым рабочим элементом. Используйте 1 как многократное, когда вы используете тяжелое ядро ​​с вычислением (ALU). Попробуйте увеличить число, чтобы скрыть задержку памяти, если у вас есть узкое место в доступе к памяти. Используйте профилировщик, чтобы определить, когда оптимальное время доступа и время ALU оптимальны.

Оптимальное соотношение для ALU для извлечения составляет 1:1 для любого устройства. Это редко достигается на практике, поэтому вы хотите, чтобы банки ALU/SIMD были насыщенными. Это означает, что ALU: выборка должна быть больше 1, когда это возможно. Менее 1 означает, что вы должны попытаться увеличить размер рабочей группы, чтобы лучше скрывать латентность памяти.

Ответ 2

Как сказал mfa, вы должны обнаружить это экспериментально. Я хотел бы добавить, что в зависимости от того, что вы вычисляете (в частности, размер заданий, т.е. меньше или больше для каждого рабочего элемента), иногда хорошей попыткой может быть:

  • Множество рабочих элементов с небольшими рабочими группами и каждым рабочим элементом небольшого размера.
  • Меньше рабочих элементов с большими рабочими группами и каждый элемент работы больше.

То есть, в основном, проверяют базовые случаи и выясняют, как это влияет на конвейер обработки.

По сути, вы должны настроить его. Я часто выполняю несколько раз для разных параметров (профилирую их), а затем создаю график поверхности, чтобы посмотреть, как он себя ведет.