Глобальный размер работы определяет, сколько задач запущено.Т.е. сколько раз будет вызываться функция ядра в общей сложности.
Локальный рабочий размер разделяет глобальный рабочий размер на локальные группы, чтобы они могли совместно использовать память и барьеры.
Причина, по которой только 32 потоказапущен из-за 1 в
clEnqueueNDRangeKernel(queue, kernel, 1, NULL, globalWorkSize, localWorkSize,
0, NULL, NULL);
Вы указали, что ядро является 1D, а не 3D, и OpenCL не будет смотреть за первыми значениями этих массивов рабочих размеров.Кроме того, локальные размеры работы должны делить глобальные размеры работы - поэтому все локальные группы будут иметь одинаковый размер.Например, глобальный {32, 3, 3}
может иметь локальные размеры:
{32,3,3}
, что делает одну локальную группу = целое ядро может совместно использовать память. {32,1,1}
создаст 3 локальные группы,каждая с размером {32,1,1}
. - Как правило, любая группировка
{32/X,3/Y,3/Z}
будет работать тогда и только тогда, когда числа можно будет разделить равномерно и сформировать X Y Z локальных групп.
CUDA против рабочих групп OpenCL
Рабочий элемент OpenCL соответствует потоку CUDA, а локальная рабочая группа OpenCL эквивалентна блоку потока CUDA.Но сетка CUDA не совсем соответствует глобальной рабочей группе, потому что CUDA использует немного другую организацию работы.
Сетка CUDA состоит из блоков потоков, и при вызове ядра необходимо указывать размеры сетки в виде блоков потоков и размеры блоков в терминах потоков.Но при вызове ядра OpenCL необходимо указать глобальную рабочую группу в терминах рабочих элементов, а не локальных групп .Это причина того, что глобальный размер группы должен делиться на размеры локальной группы (во всех измерениях).Локальные группы задаются в терминах рабочих элементов, что снова делает их эквивалентными блокам CUDA.
Пример:
Ядро CUDA с блоком из {32,32,1}
организованных потоковв сетку из {32,3,3}
потоковых блоков эквивалентно локальной рабочей группе из {32,32,1}
рабочих элементов и глобальной рабочей группе из {32*32,3*32,3*1}={1024,96,3}
рабочих элементов.
TLDR:
локальная группа = блок потока
глобальная группа = сетка * блок потока