Как правило, вы можете выбрать 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
, но специфично для устройства, а не для ядра (и это должно быть скалярное значение aka 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 - этоминимальная грануляция для выполнения в gpus, поэтому, если у вас меньше элементов в рабочей группе, она все равно будет выполняться как 32/64 потока, но отбрасывать результаты из неиспользованных потоков).