2010-06-30 10 views
9

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

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

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

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

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

Спасибо!

+0

Интересно, что вы задаете этот вопрос, как я сам его спрашивал. Мое первое предположение заключается в том, что вы сохраняете фиксированный размер рабочей группы и обрабатываете ее из связанной ветви if. – Stringer

ответ

7

Thx для связи Чад. Но на самом деле, если вы читаете:

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

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

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

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) для устройства, на котором выполнение ядра будет очереди. 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 . Значения вне этого диапазона возвращают a CL_OUT_OF_RESOURCES ошибка.

1

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

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

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

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

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

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

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