OpenCL в повседневных задачах

Недавно мы рассказывали про HSA и в ходе обсуждения преимуществ нового подхода к построению ПК затронули такую интересную тему, как GPGPU — вычисления общего назначения на графическом ускорителе. Сегодня видеоускорители AMD предоставляют доступ к своим ресурсам с помощью OpenCL — фреймворка, обеспечивающего сравнительно простое и понятное программированое высокопараллельной системы.

ad50f81b066b434397560d6d1deadc6b.jpg


Сегодня технологии OpenCL поддерживаются всеми основными игроками на рынке: возможность предоставить программам доступ к «продвинутому» ускорению (к тому же бесплатная, т.к. OpenCL не подразумевает каких-либо отчислений и роялти) явно того стоит, а от универсальности таких API выигрывают все, кто реализует поддержку OpenCL в своих продуктах.

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

GPGPU, OpenCL и немного истории


Само собой, OpenCL — не единственный способ реализовывать общие вычисления на GPU.  Помимо OpenCL на рынке присутствуют CUDA, OpenACC и C++AMP, но по-настоящему популярными и находящимися на слуху являются первые две технологии.

Разработкой стандарта OpenCL занимались те же люди, которые подарили миру технологии OpenGL и OpenAM: Khronos Group. Сама торговая марка OpenCL принадлежит компании Apple, но, к счастью для программистов и пользователей по всему миру, данная технология не является закрытой или привязанной к продукции «яблочной» компании. Помимо Apple в Khronos Goup входят такие гиганты рынка, как Activision Blizzard, AMD, IBM, Intel, NVidia и ещё с десяток компаний (в основном, производителей ARM-решений), которые присоединились к консорциуму позже.

В определённой мере OpenCL и CUDA идеологически и синтаксически схожи, от чего сообщество только выиграло. Программистам (в силу схожести определённых методов и подходов) проще использовать обе технологии, переходить от «закрытой» и привязанной к железу NVidia CUDA к универсальному и работающему везде (в том числе и на обычных многоядерных CPU, и на суперкомпьютерах на базе архитектуры CELL) OpenCL.

OpenCL в повседневном использовании


Сейчас вы подумаете «ага, будут говорить про игры и фотошоп». Нет, OpenCL способен ускорить вычисления не только связанные с графикой. Одним из самых популярных приложений, использующих возможности GPGPU является… кроссплатформенный офисный пакет LibreOffice. Поддержка OpenCL появилась в нём в 2014 году и применяется для ускорения расчётов в табличном менеджере Calc.

Вот наглядное видеосравнение производительности системы с AMD A10–7850K с графическим ядром R7 и Intel Core I5 с HD4600 на борту:

В синтетических тестах тот же AMD A10–7850K по гетерогенным вычислениям с применением OpenCL обгоняет почти вдвое более дорогой i5–4670K / 4690:

2256d8109d494a07bf60c935b9161246.png


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

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

Сюда же относятся и быстрое преобразование Фурье, и всё, что с ним связано: решение сложных дифференциальных уравнений различными методами. Отдельно можно выделить гравитационные задачи N-тел которые применяются для расчёта аэро- и гидродинамики, моделировании жидкостей и плазмы. Сложность расчётов заключается в том, что каждая частица взаимодействует с другими, законы взаимодействия достаточно сложны, а вычисления требуется проводить параллельно. Для таких задач OpenCL и возможности GPU AMD подходят как нельзя лучше, т.к. параллельные вычисления с множеством объектов и так успешно решаются на процессорах такого типа каждый день: в пиксельный шейдерах.

Структурированные решётки часто применяются в растровой графике. Неструктурированные — в вычислениях в области гидродинамики и при различных вычислениях с элементами, чьи графы имеют разный вес. Отличия структурированных решёток от неструктурированных в количестве «соседей» каждого элемента: у структурированных оно равное, у неструктурированных — разное, но и те и те отлично ложатся на возможности OpenCL по ускорению вычислений. Сложности по переносу вычислений, в основном, математические. То есть основная задача у программиста — не только «написать» работу системы, но и разработать математическое описание, которое переложит данные на аппаратные возможности с помощью OpenCL.

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

Что ещё можно ускорить с помощью OpenCL и мощных GPU?


Поиск обратного пути. Вычисления графов и динамическое программирование: сортировки, обнаружение коллизий (соприкосновений, пересечений), генерацию регулярных структур, различные алгоритмы выборки и поиска. С некоторыми ограничениями, но поддаются оптимизации и ускорению работы нейронных сетей и связанных с ними структур, но здесь, скорее, проблемы в том, что нейронные структуры просто «дорого» виртуализировать, выгоднее использовать FPGA-решения. Отлично показывают себя работы конечных автоматов (которые и так применяются в работе с GPU, например, когда речь идёт о компрессии / декомпресии видеосигнала или работе по поиску повторяющихся элементов).

OpenCL vs CUDA


Сравнивать напрямую производительность OpenCL и CUDA практически не имеет смысла. Во-первых, если мы будем сравнивать их на видеокартах AMD и NVidia, то в грубой гонке вычислительных возможностей победят видеоадаптеры AMD: современные ускорители NVidia имеют ряд ограничений по производительности в формате FP64, внедрённые самой NVidia для того, чтобы продавать «профессиональные» видеокарты для вычислений (серии Tesla и Titan Z). Их цена несоизмеримо выше, чем у аналогов по FLOPS на базе решений AMD и их «родственных» карт в номерной линейке NVidia, что делает сравнение достаточно сложным. Можно учитывать производительность-на-Ватт или производительность-на-доллар, но к чистому сравнению вычислительной мощности это не имеет практически никакого отношения: «FLOPS«ы любой ценой» слабо вяжутся с текущей финансовой обстановкой, а по производительности-на-доллар «старушка» 7970 GHz Edition (она же R9 280X) до сих пор является одной из самых выгодных видеокарт.

Во-вторых, можно попробовать сравнить OpenCL и CUDA на видеокарте от NVidia, но сама NVidia реализует OpenCL через CUDA на уровне драйвера, так что сравнение будет несколько нечестным по вполне понятным причинам.

С другой стороны, если брать во внимание не только производительность, то кое-какой анализ провести всё же можно.

OpenCL работает на куда большем списке железа, чем NVidia CUDA. Практически все CPU, поддерживающие набор инструкций SSE 3, видеоускорители начиная с Radeon HD5xxx и NVidia GT8600 заканчивая новейшими Fury / Fury-X и 980Ti / Titan X, APU от AMD, встроенная графика Intel — в общем, практически любое современное железо с несколькими ядрами может воспользоваться преимуществанми данной технологии.
9ffe27fa34d94112a1ba80aad9ec18c1.jpg
Особенности реализации CUDA и OpenCL (а также достаточно сложная документация, т.к. параллельное программирование в целом далеко не самая лёгкая область разработки), скорее, отражены в специфических возможностях и инструментах разработки, а не в области производительности.

Например, у OpenCL имеются некоторые проблемы с распределением памяти в силу «The OpenCL documentation is very unclear here».

Вместе с тем, CUDA уступает OpenCL в области синхронизации потоков — данных, инструкций, памяти, чего угодно. К тому же с помощью OpenCL можно использовать внеочередное исполнение потоков (out-of-order queues) и инструкций, а CUDA до сих пор умеет только in-order. На практике это позволяет избежать простоев процессора в ожидании данных, и эффект тем заметнее, чем длиннее ковейер процессора и больше разница между скоростью работы памяти и скоростью работы вычислительных модулей. В двух словах: чем больше мощности вы выделите под OpenCL, тем больше будет отрыв в производительности. CUDA для достижения сравнимых результатов потребует написание куда более сложного кода.

Инструменты для разработки (Дебаггер, профилер, компилятор) CUDA несколько лучше, чем аналогичные у OpenCL, но CUDA реализует API через язык C, а OpenCL — через С++, упрощая работу с объектно-ориентированным программированием, при этом оба фреймворка изобилуют «локальными» хитростями, ограничениями и особенностями.

10743ce6068a47be95353cdf3244112d.jpg

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

OpenCL предлагает более гибкие инструменты и возможности, но требует более высокого уровня подготовки от разработчиков. Общий код на чистом OpenCL должен запуститься на любом поддерживающем его железе, вместе с тем «оптимизированный» под конкретные решения (скажем, видеоускорители AMD или процессоры CELL) будет работать заметно быстрее.

© Geektimes