Вычисления на видеокарте

Начиная с момента появления первых компьютеров для вычислений традиционно использовался центральный процессор. Видеокарта же обычно использовалась только для вывода информации на монитор компьютера. Однако эволюция в области 3D-графики привела к появлению возможности использования для вычислений, в дополнение к центральному процессору, графического процессора видеокарты. Все началось с появления в спецификации DirectX 9.0 пиксельных шейдеров версии 2.0. Данные шейдеры, по сути, представляли собой настоящие программы для обработки пикселей с возможностью использования условий. Именно поэтому и зародилась идея использовать пиксельные шейдеры не только для обработки пикселей, но и для прочих вычислений. Однако при этом возник целый ряд проблем, требующих решения. Как уже было сказано выше, пиксельные шейдеры были предназначены для обработки пикселей. Поэтому возникает вопрос: Как их использовать для вычислений? Ответ на этот вопрос не столь прост, как кажется. Упрощенно можно представить, что каждый пиксель имеет некое исходное числовое значение, которое после обработки шейдером меняется по заданному алгоритму. Однако числовое значение пикселя при этом имеет не совсем обычный формат, который, естественно, не входит ни в один из стандартных типов данных большинства языков программирования. Кроме того, для получения доступа к значению пикселя, а также для программирования пиксельных шейдеров, на тот момент приходилось использовать 3D-функции из API DirectX 9. Поэтому разработчикам, желающим использовать видеокарту для вычислений, приходилось разбираться в тонкостях 3D-программирования, а это в свою очередь было довольно трудоемким процессом и препятствовало широкому распространению подобных вычислений.

Все изменилось после появления первого инструмента для разработки программ, производящих вычисления на видеокарте. Этот инструмент был создан в Стэндфордском университете и получил название Brook, а сама технология вычислений с использованием видеокарты получила общее название GPGPU (от английского General-purpose computing on graphics processing units, что дословно означает «Вычисления общего назначения на модулях обработки графики»). Данный инструмент позволял использовать ресурсы видеокарты для вычислений без специальных знаний в области 3D-графики, достаточно было владеть языком программирования С. Благодаря этому у широкого круга разработчиков и исследователей появилась возможность использования видеокарты для вычислений. Основные принципы работы Brook показаны на рис.1. Они широко используются и по сей день в аналогичных решениях, поэтому рассмотрим каждый этап работы Brook более подробно.

Рисунок 1 Общая схема работы программного средства Brook

На первом этапе разработчику необходимо написать исходный код программы на языке С и сохранить его в файл с расширением br. Например, на рис.1 это файл под именем foo.br. Затем данный файл необходимо откомпилировать с помощью специального компилятора brcc. На выходе будет получен файл с расширением cpp, который представляет собой исходные коды на языке С++ («source to source compiler» преобразует исходные коды языка С в инструкции на языке С++ с добавлением необходимых процедур и функций API DirectX 9). Данный файл уже можно использовать в составе своего проекта (например в Visual Studio 2005 Express). Однако для этого потребуется наличие необходимых библиотек и компонентов:

1) Microsoft DirectX SDK (не ниже версии за июнь 2007),
2) CGC компилятор компании NVIDIA (минимум версии 1.3b2),
3) Cygwin (базовый набор + ветка «Devel»).

Во время появления Brook (2003 год) эти дополнительные библиотеки и компоненты приходилось искать и скачивать из Интернета отдельно. Кроме того, первые версии Brook обеспечивали работу далеко не со всеми видеокартами. Последней версией Brook является версия 0.5 beta. Из своего личного опыта хочу заметить, что несмотря на то, что это бета-релиз, он обеспечивает гораздо большую совместимость и стабильную работу, чем последний финальный релиз версии 0.4. Кроме того, нельзя не отметить, что кроме всего прочего, Brook относится к так называемому «свободному программному обеспечению», а это означает, что он распространяется с открытыми исходными кодами, и любой желающий может модифицировать его под свои нужды и глубже понять его работу в случае такой необходимости.

За последние шесть лет развитие технологии GPGPU привело к появлению значительного количества инструментов, подобных Brook, а сам он в модифицированном виде под названием Brook+ вошел в состав набора программного обеспечения AMD Stream. Появление большого количества инструментов, упрощающих процесс разработки программ для вычислений на видеокарте, обусловлено, с одной стороны, желанием производителей видеокарт оптимизировать вычисления именно для своих продуктов и, с другой стороны, желанием разработчиков программных продуктов стандартизировать сам процесс разработки. В результате в настоящее время есть следующие спецификации и инструменты разработчика GPGPU:
1) AMD Stream,
2) Nvidia CUDA,
3) Intel Larrabee New Instructions,
4) OpenCL 1.0,
5) DirectX 11,
6) Оригинальный Стэндфордский Brook.

Первые три созданы тремя основными производителями видеокарт — AMD(ATI), Nvidia и Intel соответственно. Они, естественно, несовместимы друг с другом и работают только на видеокартах их разработчиков. OpenCL и DirectX, по сути, являются спецификациями, позволяющими программистам писать программы для вычислений на видеокартах, не заботясь о совместимости с оборудованием. Однако в этом случае как программистам, так и пользователям разработанного программного обеспечения, понадобятся видеокарты c поддержкой данных спецификаций (или технологий, как их любят называть разработчики), и это является серьезной проблемой, так как OpenCL поддерживают только видеокарты последних поколений, да и то не всех производителей, а поддержка DirectX 11 в данный момент реализована только в видеокартах AMD. Поэтому владельцам старых видеокарт с аппаратной поддержкой DirectX 9 придется довольствоваться возможностями оригинального Brook. Но это не настолько страшно, как кажется на первый взгляд. Современные инструменты разработки и технологии не вносят ничего нового в концепцию GPGPU. Они лишь в некоторых случаях содержат в своем составе дополнительные библиотеки, позволяющие использовать встроенные функции (например, ускорение быстрого преобразования Фурье, вычисление математических и физических функций и т.д.) внутри кода программ, без обращения к специальному компилятору и содержат в своем составе ряд компонентов, которые раньше приходилось загружать отдельно. Поэтому основную часть возможностей можно реализовать и на видеокартах предыдущих поколений, пусть и с немного сниженной точностью и скоростью вычислений.

Заканчивая данную статью, нельзя не сказать пару слов о том, зачем же нужны вычисления на видеокарте. Они используются потому, что в некоторых случаях позволяют ускорить процесс вычислений в десятки, сотни и даже тысячи раз. Так, используя видеокарту Radeon X550 для моделирования поиска сложных сигналов, мне удалось ускорить процесс вычислений примерно в сорок раз, по сравнению с использованием только мощности двухъядерного процессора Pentium D 915 с частотой 2.8 ГГц. Кроме того, получить представление о том, насколько ваша видеокарта может быть быстрее в вычислениях по сравнению с центральным процессором, можно получить из теста, входящего в состав Brook, а также из теста Sisoftware Sandra последней версии.

Виталий Сороко


Компьютерная газета. Статья была опубликована в номере 45 за 2009 год в рубрике soft

©1997-2022 Компьютерная газета