В общем, вы можете выбрать размер 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