Вопросы о глобальном и локальном размере работы

Просматривая форумы NVIDIA, я нашел эти вопросы, которые меня тоже интересуют, но за последние четыре дня на них никто не ответил. Вы можете помочь?

Исходное сообщение на форуме

Копаясь в учебниках по чтению OpenCL, некоторые вещи остались для меня неясными. Вот коллекция моих вопросов о локальных и глобальных размерах работы.

  1. Должен ли global_work_size быть меньше CL_DEVICE_MAX_WORK_ITEM_SIZES? На моей машине CL_DEVICE_MAX_WORK_ITEM_SIZES = 512, 512, 64.

  2. Является ли CL_KERNEL_WORK_GROUP_SIZE рекомендуемым work_group_size для используемого ядра?

    1. Or is this the only work_group_size the GPU allows? On my machine CL_KERNEL_WORK_GROUP_SIZE = 512
  3. Нужно ли делиться на рабочие группы или можно только одну, но без указания local_work_size?

    1. To what do I have to pay attention, when I only have one work group?
  4. Что означает CL_DEVICE_MAX_WORK_GROUP_SIZE? На моей машине CL_DEVICE_MAX_WORK_GROUP_SIZE = 512, 512, 64

    1. Does this mean, I can have one work group which is as large as the CL_DEVICE_MAX_WORK_ITEM_SIZES?
  5. Должен ли global_work_size быть делителем CL_DEVICE_MAX_WORK_ITEM_SIZES? В моем коде global_work_size = 20.


person Framester    schedule 18.10.2010    source источник


Ответы (1)


В общем, вы можете выбрать размер global_work_size настолько большим, насколько хотите, в то время как local_work_size ограничивается базовым устройством/аппаратным обеспечением, поэтому все результаты запроса будут сообщать вам возможные размеры для local_work_size вместо global_work_size. единственным ограничением для global_work_size является то, что он должен быть кратен local_work_size (для каждого измерения).

Размеры рабочих групп определяют размеры рабочих групп, поэтому, если CL_DEVICE_MAX_WORK_ITEM_SIZES равен 512, 512, 64, это означает, что ваш local_work_size не может быть больше, чем 512 для измерения x и y и 64 для измерения z.

Однако существует также ограничение на размер локальной группы в зависимости от ядра. Это выражается через CL_KERNEL_WORK_GROUP_SIZE. Ваш совокупный размер рабочей группы (как в произведении всех измерений, например, 256, если у вас есть локальный размер 16, 16, 1) не должен превышать это число. Это связано с ограниченными аппаратными ресурсами, которые должны быть разделены между потоками (из результатов вашего запроса я предполагаю, что вы программируете на графическом процессоре NVIDIA, поэтому объем локальной памяти и регистров, используемых потоком, будет ограничивать количество потоков, которые могут быть выполняются параллельно).

CL_DEVICE_MAX_WORK_GROUP_SIZE определяет максимальный размер рабочей группы так же, как CL_KERNEL_WORK_GROUP_SIZE, но зависит от устройства, а не от ядра (и это должно быть скалярное значение, также известное как 512).

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

Однако вы должны отметить, что использование только одной рабочей группы, как правило, не является хорошей идеей с точки зрения производительности (и зачем использовать OpenCL, если производительность не имеет значения). Как правило, рабочая группа должна выполняться на одном вычислительном блоке, в то время как у большинства устройств их будет больше одного (у современных ЦП их 2 или более, по одному на каждое ядро, а у современных графических процессоров их может быть 20 и более). Кроме того, даже одна вычислительная единица, на которой работает ваша рабочая группа, может быть использована не полностью, поскольку несколько рабочих групп могут выполняться на одной вычислительной единице в стиле SMT. Для оптимального использования графических процессоров NVIDIA вам потребуется 768/1024/1536 потоков (в зависимости от поколения, то есть G80/GT200/GF100), выполняющихся на одном вычислительном блоке, и хотя сейчас я не знаю цифр для AMD, они находятся в одинаковая величина, поэтому хорошо иметь более одной рабочей группы. Кроме того, для графических процессоров обычно рекомендуется иметь рабочие группы с не менее чем 64 потоками (и числом потоков, кратным 32/64 (nvidia/amd) на рабочую группу), потому что в противном случае вы снова снизите производительность (32/64 — это минимальная зернистость для выполнения на gpu, поэтому, если у вас меньше элементов в рабочей группе, она все равно будет выполняться как 32/64 потока, но отбрасывать результаты неиспользуемых потоков).

person Grizzly    schedule 18.10.2010
comment
Большое Вам спасибо. У меня есть одна вещь, которую я должен спросить: когда вы имеете в виду меньше, вы имеете в виду ‹ или ‹=? - person Framester; 18.10.2010
comment
Я бы отредактировал рекомендацию о том, что не рекомендуется не указывать размер рабочей группы. Так как для многих операций это лучший выбор. - person DarkZeros; 15.10.2013
comment
while modern CPUs can have up to 20) Должно ли быть так, что графических процессоров может быть до 20? - person user1937198; 04.06.2014