Должен ли глобальный размер работы быть кратным размеру рабочей группы в OpenCL? - PullRequest
10 голосов
/ 30 июня 2010

Здравствуйте. Должен ли глобальный размер работы (измерения) быть кратным размеру рабочей группы (измерения) в OpenCL?

Если это так, то существует ли стандартный способ обработки матриц, не кратный рабочей группе?размеры?Я могу представить две возможности:

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

Увеличьте измерения глобальной работы до ближайшего кратного измерения рабочей группы, сохранив всевходной и выходной буферы одинаковы, но проверяют границы в ядре, чтобы избежать segfaulting, т.е. ничего не делают для рабочих элементов вне границ желаемого вывода.(Это кажется лучшим способом.)

Будет ли работать второй способ?Есть ли способ лучше?(Или это не обязательно, потому что измерениям рабочей группы не нужно делить глобальные рабочие измерения?)

Спасибо!

Ответы [ 3 ]

7 голосов
/ 02 июля 2010

Спасибо за ссылку Чад.Но на самом деле, если вы читаете:

Если указан local_work_size, значения, указанные в global_work_size [0],… global_work_size [work_dim - 1], должны делиться равномерно на соответствующие значения, указанные в local_work_size [0],… local_work_size [work_dim - 1].

Так что ДА, локальный размер работы должен быть кратным глобальному размеру работы.

Я также думаю, что назначение глобальногоразмер работы с точностью до кратного и осторожность с границами должна сработать, я опубликую комментарий, когда найду время попробовать его.

1 голос
/ 13 апреля 2016

Это, кажется, старый пост, но позвольте мне обновить этот пост новой информацией. Надеюсь, это может помочь кому-то еще.

Должен ли глобальный размер работы (размеры) составлять несколько рабочих групп? Размер (размеры) в OpenCL?

Ответ: верно до OpenCL 2.0. До CL2.0 ваш глобальный рабочий размер должен быть кратным локальному рабочему размеру, в противном случае вы получите сообщение об ошибке при выполнении clEnqueueNDRangeKernel.

Но с CL2.0 это больше не требуется. Вы можете использовать любой глобальный размер работы, который соответствует размерам вашего приложения. Однако, пожалуйста, помните, что аппаратная реализация все еще может использовать «старый» способ, который означает заполнение глобального размера рабочей группы. Следовательно, производительность сильно зависит от аппаратной архитектуры. Вы можете увидеть совершенно разную производительность на разных аппаратных средствах / платформах. Кроме того, вы хотите сделать ваше приложение обратно совместимым с поддержкой более старой платформы, которая поддерживает только CL до версии 1.2. Итак, я думаю, что эта новая функция, добавленная в CL2.0, предназначена только для простого программирования, для улучшения управляемости и обратной совместимости. Я предлагаю вам по-прежнему использовать следующий метод, упомянутый вами:

Увеличьте размеры глобальной работы до ближайшего кратного измерений рабочей группы, сохраняя все входные и выходные буферы то же самое, но проверка границ в ядре, чтобы избежать сегфагов, т.е. ничего на рабочих элементах выходит за пределы желаемого результата. (Это кажется, лучше.)

Ответ: вы абсолютно правы. Это правильный способ справиться с таким делом. Тщательно спроектируйте размер локальной рабочей группы (принимая во внимание такие факторы, как использование регистра, попадание в кэш, ошибка доступа к памяти и т. Д.). А затем добавьте ваш глобальный рабочий размер, кратный локальному рабочему размеру. Тогда тебе пора.

Еще одна вещь, которую следует учитывать, это то, что вы можете использовать объект изображения для хранения данных вместо буфера, если в вашем ядре достаточно много работы по проверке границ. Для изображения проверка границ выполняется автоматически аппаратными средствами, в большинстве реализаций практически нет накладных расходов. Поэтому, добавляя ваш глобальный рабочий размер, сохраняйте ваши данные в объекте изображения, тогда вам просто нужно написать свой код, как обычно, не беспокоясь о проверке границ.

1 голос
/ 01 июля 2010

Согласно стандарту это не должно быть из того, что я видел.Я думаю, что справился бы с веткой, но я не знаю точно, какую матричную операцию вы делаете.

http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf#page=131

global_work_size указывает намассив work_dim значений без знака, которые описывают количество глобальных рабочих элементов в work_dim измерениях, которые будут выполнять функцию ядра.Общее количество глобальных рабочих элементов вычисляется как global_work_size[0] * ... * global_work_size[work_dim – 1].

Значения, указанные в global_work_size + соответствующие значения, указанные в global_work_offset, не могут превышать диапазон, определяемый какsizeof(size_t) для устройства, на котором выполнение ядра будет поставлено в очередь.sizeof(size_t) для устройства можно определить с помощью CL_DEVICE_ADDRESS_BITS в таблице 4.3.Если, например, CL_DEVICE_ADDRESS_BITS = 32, т.е. устройство использует 32-разрядное адресное пространство, size_t - это 32-разрядное целое число без знака, а значения global_work_size должны находиться в диапазоне 1 .. 2 ^ 32 - 1Значения вне этого диапазона возвращают ошибку CL_OUT_OF_RESOURCES.

...