Opencl: Мы Дождались — Версия 1.1 От Nvidia, А Что Нового?



Немного истории или обещанные три года ждут Чуть больше года назад компания Khronos Group представила новую версию OpenCL 1.1, и nVidia сразу же похвасталась, что у нее есть предварительная версия драйвера, готового поддерживать новый стандарт. Все бы ничего, но пререлиз не является рабочим инструментом (в официальных драйверах полно ошибок, а в тестовой версии тем более), поэтому разработчики честно дождались выхода новой версии.

CUDA 4 вышел, но OpenCL по-прежнему отсутствовал.

Более того, даже предрелизная версия OpenCL была исключена из новой версии драйверов, т.е.

мне пришлось выбирать между старым драйвером с CUDA 3 + OpenCL 1.1 или новым драйвером с CUDA 4 + OpenCL 1.0. Но сегодня это произошло! Разработчикам пришло письмо о том, что в официальных драйверах 280.13 уже доступна финальная версия, хотя это пока еще бета-версия, но это продлится недолго.

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



Что нового в OpenCL 1.1

Пройдемся по списку Хронос Групп, и если я вспомню что-то, чего там нет, то добавлю.



Безопасность потоков хоста
Потокобезопасность — полезная вещь; теперь нам не нужно думать о том, что вызывать, когда и как синхронизировать.

Насколько это актуально – хороший вопрос; пока используется одна карта, толку от нее мало.

Когда карточек много и у каждой свой ход, то да, жизнь становится проще.

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

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



Объект суббуфера
По сути, теперь вы можете разделить буфер на несколько частей и отправить нужный кусок на нужное устройство.

Опять же полезно в случае использования нескольких видеокарт и улучшения портативности.

А целостность данных сохраняется, когда нет необходимости делать для каждой карты отдельный буфер.

В общем, можно было бы обойтись и без него, но он пригодится.

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



Пользовательские события
Появились команды клкреатеусеревент И клсетусеревентстатус , что позволяет пользователю создавать свои собственные события.

Раньше можно было привязать всё только к тем событиям, которые происходили после выполнения команд OpenCL. Опять же можно обойтись и без этого (просто добавляя в очередь новые команды по какому-то событию), но стало удобнее.



Обратные вызовы событий
Есть функция клсетевентколлбэк , который регистрирует пользовательские функции, которые вызываются при соответствующем изменении статуса события.

Вы можете добавить несколько пользовательских функций, но порядок их вызова не определен.

Мне уже нравится это дополнение, раньше приходилось проверять статус события каждые несколько мс, а теперь все удобно, а главное экономятся эти несколько секунд и упрощается весь процесс.

Это начинает напоминать мне что-то вроде ActionScript :) Кстати, еще одной полезной функцией может быть clSetMemObjectDestructorCallback , который позволяет вам добавить пользовательскую функцию, которая вызывается при удалении объекта cl_mem.

3-компонентный вектор
Раньше были векторы размером 2, 4, 8, 16, но сейчас мы все живем в трехмерном пространстве и трехмерные векторы — популярная вещь.

А если использовать 4-х мерные, то вы уже теряете целый регистр, а это большая трата.

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

Глобальное рабочее смещение, которое позволяет ядрам работать с разными частями NDRange.
Честно говоря, я всегда думал, что это уже случалось раньше.

Да, и это есть в официальной документации обеих версий.

Если кто-нибудь знает, что здесь изменилось, пожалуйста, напишите.



Чтение, запись и копирование 1D, 2D или 3D прямоугольной области буферного объекта.

Новые возможности clEnqueueReadBufferRect, clEnqueueWriteBufferRect и clEnqueueCopyBufferRect , которые позволяют копировать прямоугольную область буфера.

Те.

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

Лично мне никогда не приходилось этого делать, но для больших матриц это должно быть полезно.



Зеркальная повторная адресация
Если вы сохраняете изображение как текстуру, вы можете использовать CLK_ADDRESS_MIRRORED_REPEAT чтобы при выходе за границу текстуры результат получался так, как будто ее отражение там.

Причём это срабатывает столько раз, сколько необходимо, отражения как бы чередуются.



Различные дополнения и улучшения
CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE аргумент функции clGetKernelWorkGroupInfo , должен сообщить нам множитель размера группы, подходящий для данного устройства.

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

Но я еще не пробовал, поэтому могу ошибаться.

CL_CONTEXT_NUM_DEVICES аргумент функции клжетконтекстинфо сообщит нам, сколько устройств находится в контексте.

Одна полезная вещь, позволяющая узнать, какая версия OpenCL используется в программе, — это макросы.

CL_VERSION_1_0 и CL_VERSION_1_1 Они также добавили в стандарт такие расширения, как: cl_khr_byte_addressable_store cl_khr_global_int32_base_atomics, cl_khr_global_int32_extended_atomics, cl_khr_local_int32_base_atomics, cl_khr_local_int32_extended_atomics .

И префикс для встроенных атомарных операций был изменен с атом_ на атомный_ .

Появилось 2 новых расширения: cl_khr_gl_event и cl_khr_d3d10_sharing .

Также есть несколько новых команд: get_global_offset, минмаг, Максмаг async_work_group_strided_copy, век_шаг, перетасовать, перемешать2. Я бы описал все обновления, но спать хочется, надеюсь этот список будет кому-то полезен.

PS: Опять же, у меня в посте нет ни строчки кода, обещаю позже исправить, у меня много идей по примерам и тестам, а пока проживем без этого :) PS2: В моем последнем посте OpenCL: универсальность и высокая производительность или все не так просто? они спросили о книге про OpenCL, но мне нечего было ответить.

Итак, сегодня я обнаружил, что всего неделю назад вышла книга «Руководство по программированию OpenCL» .

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

Теги: #opencl #высокая производительность #gpu #GPGPU #1.1 #changelog #Высокая производительность

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.