Опрос
Вы участвуете в программе Windows Insider?
Популярные новости
Обсуждаемые новости

15.07.2010 11:00 | deeper2k

Думаю, аббревиатура CUDA в достаточной степени на слуху, и знакома многим из вас. Википедия подсказывает нам, что CUDA расшифровывается как Compute Unified Device Architecture, что можно вольно перевести как "архитектура устройств с поддержкой универсальных вычислений". Этими устройствами являются видеокарты производства NVidia. Поддержку CUDA обеспечивают карточки GeForce, начиная с 8xxx и выше, а также модельный ряд "профессиональной серии" - Quadro и Tesla. Таких устройств выпущено очень большое количество - от самых дешевых до супердорогих, и распространены они повсеместно. Тем интереснее становится сама технология - успешное её применение сулит хорошее преимущество по производительности. Разумеется, не всё так просто. Создание многопоточных программ, даже исполняемых на привычном CPU, сопряжено с определённым количеством трудностей. Лишь небольшое число приложений являются "распараллеленными", и дело тут не столько в технической сложности, сколько в характере задач и подходов к их решению. Чего уж тут говорить про GPGPU-вычисления - они имеют свои характерные особенности, ограничивающие сценарии применения. Вообще, это тема отдельного обсуждения, и я не стану в неё углубляться - предлагаю вместо этого подробнее познакомиться с CUDA и возможностями применения её в .NET приложениях.



Часть 1. Аппаратная платформа
Технология CUDA представляет собой аппаратно-программный комплекс, обеспечивающий использование мощностей видеоадаптера для неграфических вычислений. Чтобы лучше понимать суть процессов, происходящих в GPU при выполнении таких вычислений, давайте ознакомимся с её аппаратной частью.


Современные видеоадаптеры являются технически достаточно сложными устройствами, фактически, это "мини-компьютер в компьютере": на одной плате расположены вычислительные модули, память, контроллеры и др. устройства. Рассмотрим наиболее важные для нас как прикладных программистов детали: устройство CUDA-процессора и особенности его работы.

GPU NVidia по характеру работы являются SIMD-устройствами: Single Instruction, Multiple Data, т.е. некоторый входной поток данных, состоящий из однородных элементов, обрабатывается одной инструкцией (или набором инструкций). В качестве результата мы также получаем однородный поток элементов. При этом каждый элемент может быть обработан независимо от остальных, что позволяет обрабатывать элементы параллельно:


Строго говоря, используется не принцип SIMD, а SIMT - single instruction, multiple threads. Общая задача - обработка входного потока данных - делится на множество мелких подзадач, каждая из которых обрабатывается своей нитью. Нити же исполняются параллельно на вычислительных модулях, в качестве которых используется набор потоковых мультипроцессоров (SM, Streaming Multiprocessor в англоязычной терминологии). Давайте посмотрим, из чего состоит SM архитектуры Tesla 8:


Роль "рабочей лошадки" здесь играют SP - потоковые процессоры (streaming processor), или CUDA-процессоры. Непосредственно они выполняют инструкции по обработке данных. Из рисунка видно, один мультипроцессор включает в себя 8 таких исполнительных блоков. Кроме них есть два специальных модуля SFU - special function unit, предназначенных для выполнения сложных вычислений (например, тригонометрических).

Далее, в состав SM входит набор регистров (на схеме - Registers). Их количество в SM архитектуры Tesla 8 равно 8192, разрядность каждого из них - 32 бита. Кроме того, SM содержит ещё и общую для всех CUDA-ядер память (Shared Memory), суммарным объёмом 16 Кбайт. Фактически, и блок регистров, и общая память - наиболее близкая к потоковому процессору единица памяти, взаимодействие с ней очень быстрое, значительно быстрее, чем с DRAM - модулями памяти, распаянными на плате. Оно и понятно - Register и Shared Memory находятся на одном кристалле с SP. Главное отличие между регистровой и разделяемой памятью в том, что регистры распределяются на этапе компиляции, и во время выполнения строго разграничены между потоками, выполняющимися на CUDA-ядрах. Т.е. их распределением управляет компилятор. В то время как Shared Memory могут использовать все нити выполнения программы, и эта память доступна программисту посредством ключевого слова shared.

Именно такие SM используются при построении видеоадаптеров поколения 8xx. Например, видеокарта GeForce 8500GT включает в себя 2 потоковых мультипроцессора (т.е. 16 CUDA-процессоров), а GeForce 8800GT на чипе G92b - целых 14 штук (т.е. 112 процессоров)! Разумеется, чем больше CUDA-процессоров доступно и на чем более высокой частоте работает шейдерный блок, тем выше максимальная производительность. Впрочем, на возможности устройства влияет ещё много факторов: например, производительность подсистемы памяти и т.д. Традиционно для DRAM используется GDDR2 и GDDR3 память с самыми различными характеристиками. Однако, стали появляться решения на базе GDDR5 чипов - к ним относятся флагманские продукты NVidia.

Потоковые мультипроцессоры в свою очередь находятся внутри TPC - Texture Processing Claster, т.е. блока обработки текстур. Схематически его можно изобразить так:


Здесь TEX - это блок доступа к текстурам. Видно, что один блок обработки текстур содержит 2 мультипроцессора. Напомню, это относится к архитектуре Tesla 8, у более поздней продукции схема немного иная. Собственно, TPC - наиболее крупная структурная единица. Шейдерный блок видеокарты состоит из набора таких вот модулей и набора различных вспомогательных схем служащих, например, для организации доступа к DRAM.

SM архитектуры Tesla 10 (чип GT200) содержат также 16 процессоров, но в дополнение имеют блок для выполнения сложных операций с повышенной точностью (Double precision):


Очевидно, что выполнение инструкций двойной точности достаточно "дорого" - соответствующий блок всего один внутри SM, да и работает он медленнее потокового процессора. В реальности соотношение производительности DP по сравнению с SP колеблется около 1/4. Мультипроцессоры такого вида содержатся, например, в видеоадаптерах GTX260, GTX280 и др. Соответственно, и блок обработки текстур (TPC) выглядит немного иначе:


Т.е. содержит в себе уже 3 мультипроцессора. Этим и объясняется кратность тройке количества CUDA-процессоров у видеокарт на основе GT200. Например, есть модификация GeForce GTX260, которая имеет 216 потоковых процессоров. Легко догадаться, что 216 SP "рассчитывается" как 8 (SP внутри SM) х 3 (SM в TPC) x 9 (количество TPC).

С выходом первых DX11-совместимых решений от AMD конкуренция на рынке усилилась, и в первом квартале этого года NVidia представила образцы продукции на базе новейшей архитектуры Fermi - видеоадаптеры GTX480 и GTX470. Потоковые мультипроцессоры, входящие в состав GF100 (именно такой код имеет новое детище), имеют "на борту" целых 32 ядра CUDA, улучшенный планировщик выполнения вычислений. Соответственно, увеличилось количество регистров, блоков специальных функций SFU, объём разделяемой памяти и т.д. SM в новой архитектуре объединяются в кластеры Graphics Processing Cluster, каждый из которых содержит четыре SM и один блок растеризации Raster Engine. Если посмотреть ещё "на уровень выше", то чип GF100 имеет 4 кластера GPC, снабжен шестью 64-битными контроллерами памяти с поддержкой GDDR5, и т.о. максимально содержит 512 ядер CUDA. В конечных продуктах часть ядер может быть недоступна, поскольку уровень выхода годных чипов пока не так высок, как ожидалось, и приходится "отрезать" некачественные блоки. Это же позволяет варьировать мощность разных видеокарт и, в конечном итоге, их цену. GeForce GTX480 имеет 480 потоковых процессоров, а GTX470 и того меньше - всего 448. Кроме того, значительно ускорены вычисления с двойной точностью, и с этим связан интересный момент. Видеокарты игровой серии GeForce потенциально имеют значительно большую пиковую производительность, которая в серийно выпускаемых образцах снижена, что позволяет выпустить т.н. "профессиональные" ускорители серии Tesla, которые уже будут работать на полную мощность, иметь схемы коррекции ошибок ECC и т.д. И стоить они будут уже гораздо дороже.

Ок, что "под капотом" CUDA-совместимых карточек, примерно понятно. В чём же принципиальная разница между многоядерным CPU и GPGPU? На мой взгляд, лучше всего это отражает следующая картинка из руководства NVidia CUDA programming guide:


Значительная часть кристалла у GPU отводится на собственно вычислительные блоки, в то время как доля кэша и управляющих элементов ниже. У CPU же иной принцип - довольно "жирный" кэш, всего несколько ядер, которые при это умеют исполнять большой набор инструкций и работают обычно на более высокой частоте. Дальше, при рассмотрении программной модели и способа выполнения CUDA-программ, мы увидим, как такая разница в архитектуре отражается на принципах программирования. Чтобы обеспечить столь большое количество ядер данными, GPU просто необходим широкий канал доступа к памяти. Что, собственно и реализовано (картинка опять же из руководства):


Эта диаграмма наглядно показывает, насколько шире канал доступа к DRAM у GPU NVidia по сравнению с CPU производства Intel, выпускаемыми в аналогичный период времени. Наличие большого количества вычислительных блоков не могло сказаться бесследно на максимальной производительности. Приведу заключительный график из того же документа:


Характеристики пиковой производительности поистине впечатляют! Разумеется, чтобы выпустить этого "джинна" и получить значительный прирост при исполнении на GPU, нужно потрудиться и адаптировать свои алгоритмы для исполнения на CUDA-ядрах. Конечно, такие мощности не даются бесплатно, и за высокую производительность приходится платить достаточно высоким энергопотреблением. В частности, флагман CUDA-обработки GTX480 потребляет при номинальных частотах до 250Вт.

Названия вроде 8800GT, GTX285 и пр. удобны для маркетологов, однако по ним довольно сложно догадаться, что собой представляет устройство с точки зрения CUDA. Чтобы устранить это недоразумение, было введено понятие CUDA compute capability - этакая "версия" возможностей устройства. В руководстве NVidia CUDA programming guide, размещенном на сайте NVidia, приведён список видеочипов с их характеристиками, в т.ч. compute capability, а также описание возможностей каждой "версии". С помощью него вы легко можете определить, на что с точки зрения CUDA способна ваша видеокарта.

Итак, вкратце основные выводы:

  • CUDA использует принцип SIMT;
  • нити выполняются на потоковых процессорах;
  • потоковые процессоры размещаются в потоковых мультипроцессорах;
  • мультипроцессор содержит различного вида память, планировщик нитей, модули специальных функций;
  • вычислительная мощность прямо пропорциональна числу мультипроцессоров;
  • с CUDA совместимо огромное число видеоадаптеров, начиная от GeForce 8300 и заканчивая GeForce GTX480.



Vitus, TheVista.Ru Team,
Июль 2010

Комментарии

Не в сети

Спасибо, интересно. Нашёл пару ошибочек:

- "В качестве результата также мы также получаем однородный поток элементов."
- "В реальности соотношение производительности DP по сравнению с SP колеблется ок. 1/4." (это означает "около"?)
- "Ок, что "под капотом" CUDA-совместимых карточек, примерно понятно." (не знаю, стоит ли вообще использовать в тексте OK, но в крайнем случае это должны быть латинские символы)
- Не хватает точки в конце статьи.

17.07.10 17:25
0
Не в сети

smath, спасибо за комментарий!

"В реальности соотношение производительности DP по сравнению с SP колеблется ок. 1/4" - означает, что операция double точности примерно в 4 раза медленее её же, но с float числами

19.07.10 10:32
0
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
420.55 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Все права принадлежат © ms insider @thevista.ru, 2022
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.036 секунд (Общее время SQL: 0.017 секунд - SQL запросов: 55 - Среднее время SQL: 0.00031 секунд))
Top.Mail.Ru