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

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

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

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

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

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

спасибо!

3 ответов


Thx для ссылки Чад. Но на самом деле, если Вы читаете эти строки:

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

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

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


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

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) для устройства на каким будет выполнение ядра поставить в очередь. The sizeof(size_t) для a прибор можно определить используя 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 ошибка.


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

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

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

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

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

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

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