Современные графические процессоры: насколько они «умны»?

11

Существует множество ресурсов по 3D-программированию (OpenGL или DirectX) и соответствующим графическим конвейерам, но мне интересно, на каком уровне они реализованы в современном графическом процессоре.

До сих пор я был в состоянии узнать, что произошел переход от очень специализированной схемы, которая реализует различные этапы графического конвейера, к более общему подходу. Это преобразование было частично отражено в 3D API в виде программируемых шейдеров. Кажется, что большинство транзисторов предназначены для массивно параллельных блоков SIMD, которые выполняют фактические инструкции шейдера.

Но как насчет остальной части графического конвейера? Это все еще реализовано в оборудовании?

Является ли современный GPU (например, Nvidia Fermi) в основном набором «глупых» SIMD-массивов, которые снабжаются инструкциями и данными из ЦП и различными кэшами, и вся фактическая логика, которая отображает графический конвейер в эти инструкции, происходит в графическом драйвере ?

Или есть какие-то блоки управления где-то в графическом процессоре, которые преобразуют входящие высокоуровневые команды и потоки данных (скомпилированные шейдерные программы, данные и атрибуты вершин и текстуры) в фактические инструкции SIMD и заботятся о синхронизации, распределении памяти и т. Д.?

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

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

lxgr
источник

Ответы:

8

До сих пор я был в состоянии узнать, что произошел переход от очень специализированной схемы, которая реализует различные этапы графического конвейера, к более общему подходу. Это преобразование было частично отражено в 3D API в виде программируемых шейдеров. Кажется, что большинство транзисторов предназначены для массивно параллельных блоков SIMD, которые выполняют фактические инструкции шейдера.

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

Является ли современный GPU (например, Nvidia Fermi) в основном набором «глупых» SIMD-массивов, которые снабжаются инструкциями и данными из ЦП и различными кэшами, и вся фактическая логика, которая отображает графический конвейер в эти инструкции, происходит в графическом драйвере ?

Определенные вещи все еще сделаны в оборудовании; другие нет. Например, ROP все еще используются на самом последнем этапе для передачи пиксельных данных в чипсет VGA. Примечание. Я использую здесь «набор микросхем VGA» в качестве общего термина для обозначения механизма, который передает видеосигнал на ваш монитор, независимо от того, является ли он действительно «VGA» в любом отношении.

В целом, верно, что современные архитектуры графических процессоров, такие как Nvidia Fermi и AMD Southern Islands, по большей части представляют собой массивно параллельные процессоры, где у них есть собственный набор команд, и каждое отдельное «ядро» чрезвычайно слабое, но есть целом много ядер (иногда несколько тысяч). Но там все еще есть графическое оборудование:

  • Аппаратное декодирование видео часто выполняется, в основном, с использованием чипов с фиксированной функцией. Это особенно верно, когда задействован DRM (Управление цифровыми ограничениями). Иногда «аппаратное» декодирование видео на самом деле означает набор инструкций с прошивкой, которые просто выполняются как обычные старые задачи для ядер SIMD. Это действительно зависит.

  • За исключением очень небольшого числа плат Nvidia для конкретных вычислений (Tesla), почти все видеокарты "generic SIMD" имеют полный набор аппаратного обеспечения, предназначенного для вывода видео. Вывод видео отличается от рендеринга; Элементы вывода фиксированной функции включают в себя кодеки LVDS / TMDS / HDMI / DisplayPort, HDCP и даже обработку звука (в основном небольшой DSP), поскольку HDMI поддерживает звук.

  • «Графическая память» по-прежнему хранится на борту вместе с графическими процессорами, так что им не нужно пересекать болтливую шину PCIe с относительно высокой задержкой, чтобы попасть в системную память, которая сама по себе медленнее и требует больше времени, чем более дорогие, более высокое качество, более быстрая графическая память (например, GDDR5), которая имеет меньшую емкость, но более высокую скорость, чем системная память. Процесс сохранения содержимого в графической памяти и извлечения его оттуда в графический процессор или в процессор все еще в значительной степени является операцией с фиксированной функцией. Некоторые графические процессоры имеют своего рода «IOMMU», но этот блок управления памятью отличается (отдельно) от центрального процессора. Однако это не так для современных графических процессоров Intel, интегрированных в их процессоры (Sandy и Ivy Bridge), где архитектура памяти почти полностью «согласована». системная память) и чтения из графической памяти для процессора столь же дешевы, как и для графического процессора.

Или есть какие-то блоки управления где-то в графическом процессоре, которые преобразуют входящие высокоуровневые команды и потоки данных (скомпилированные шейдерные программы, данные и атрибуты вершин и текстуры) в фактические инструкции SIMD и заботятся о синхронизации, распределении памяти и т. Д.?

«Родной» язык SIMD почти всегда генерируется драйвером в программном обеспечении, а не собственной прошивкой графического процессора. Это особенно верно для функций уровня DirectX 9 / OpenGL 2.x. Шейдеры, написанные на языках высокого уровня, таких как HLSL, GLSL или ассемблер ARB OpenGL ARB, в конечном итоге переводятся драйвером в инструкции GPU, ударяя по определенным регистрам и выполняя необходимые циклы PCIe для отправки через пакетные буферы вычислений и / или визуализации. команды.

Некоторые вещи, такие как аппаратная тесселяция (DirectX 11 / OpenGL 4.0), снова внедряются в аппаратные средства фиксированным образом, подобно тому, как они делали почти все в старые времена. Это связано с тем, что, опять же, ограничения производительности требуют, чтобы наиболее эффективный способ выполнения этих вычислений состоял в том, чтобы иметь для этого выделенную схему, а не иметь встроенное ПО или драйвер, «программирующий» SIMD для этого.

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

AMD и Intel имеют открытую документацию о своих последних графических процессорах, а также полностью работающие графические драйверы с открытым исходным кодом для Linux (см. Проекты Mesa и Direct Rendering Manager). Если вы посмотрите на часть кода в этих драйверах, вы будете смеяться, потому что разработчики графических драйверов на самом деле должны реализовывать геометрию таких вещей, как рисование различных форм или шаблонов, в «программном обеспечении» (но с использованием аппаратных команд для передачи реальных данных). на аппаратное обеспечение для обработки), потому что больше нет ни прошивки графического процессора, ни фиксированных функций, чтобы полностью обработать его аппаратно :) Это забавно, что им нужно сделать, чтобы поддерживать OpenGL 1.x / 2.x на новых аппаратное обеспечение.

Эволюция вроде как пошла так:

  • Давным-давно (до того, как 3D-рендеринг в реальном времени считался возможным): трассировка лучей на процессоре была нормальной для рендеринга не в реальном времени. Для простой графики, как вы видели в ранних версиях Windows, процессор был достаточно быстрым, чтобы рисовать простые фигуры (прямоугольники, символы шрифта, шаблоны затенения и т. Д.) Без аппаратного обеспечения с фиксированной функцией, но он не мог рисовать слишком сложные вещи.
  • Давным-давно (OpenGL 1.x): почти все реализовано на твердотельном оборудовании; «электрически» фиксированные функции были нормой даже для базовых операций
  • Некоторое время назад (OpenGL 2.x): начался переход к созданию более программируемых графических процессоров. «Фрагментные шейдеры» (то есть пиксельные шейдеры) на 5-летнем оборудовании могут почти выполнять произвольные вычисления, такие как ЦП, но это ограничено архитектурой, которая все еще очень ориентирована на графику. Следовательно, OpenCL / DirectCompute не доступны на этом оборудовании.
  • В последнее время (OpenGL 3.x): переход к графическим процессорам общего назначения в основном завершен, но они, конечно, оптимизированы для рабочих нагрузок, включающих большие матрицы данных (представьте линейную алгебру), представляемых пакетами, а не процессоры, которые могут эффективно работать длинные последовательности очень маленьких данных (1 + 1, 2 * 4, 5 * 6 в последовательности и т. д.). Вычисления общего назначения доступны через OpenCL, CUDA и т. д., но аппаратное обеспечение все еще не является полноценным «SIMD-сопроцессором» потому что (а) вам все равно придется забивать аппаратные регистры, чтобы получить доступ к функциональности графического процессора; (б) считывание из видеопамяти GPU очень медленное из-за нагрузки на шину PCIe (считывание из GPU не очень оптимизировано в текущей архитектуре); (c) архитектура памяти и кеша не согласована с процессором; множество устаревших аппаратных средств с фиксированными функциями все еще находится в разработке.
  • Настоящее время (OpenGL 4.x): избавился от многих устаревших аппаратных средств с фиксированными функциями. Несколько улучшилась задержка чтения GPU. IOMMU допускает (переведенное) аппаратное отображение между VRAM и системной памятью. Также введена аппаратная тесселяция, возвращающая элементы фиксированной функции.
  • Будущее ( HSA): GPU в основном сопроцессор. Он практически полностью интегрирован с процессором с очень небольшим сопротивлением (для чтения / записи) между графическим процессором и процессором, даже для выделенных графических процессоров на шине PCIe. Полностью связная архитектура памяти - «mi memoria es su memoria» (моя память - ваша память). Программы пользовательского пространства могут читать из «VRAM» так же, как они читают из системной памяти без прокладки драйвера, и аппаратное обеспечение позаботится об этом. У вас есть процессор для «последовательной» обработки (сделайте это, затем сделайте это, затем сделайте это, затем сделайте это) для скромных объемов данных, и графический процессор для «параллельной» обработки (выполните эту операцию для этого огромного набора данных и разделите его до того, как вы считаете нужным). На плате, на которой установлен графический процессор, все еще могут быть ROP, HDMI-кодек и т. Д., Но это необходимо для вывода на дисплей,
allquixotic
источник
Ваше последнее замечание замечательно, и оно также относится не только к OpenGL1.x / 2.x типам вещей. Из-за невероятной сложности логики в графических процессорах почти очевидно, что где-то будут ошибки. Обычно большинство ошибок в логике выявляются до того, как они превращаются в физическую микросхему, но могут быть некоторые странные угловые случаи, которые все еще могут возникать. Когда это происходит, драйверы должны будут реализовать саму функцию, чтобы обойти ошибочную часть оборудования. Подобные вещи часто являются причиной того, что вы можете получить улучшения функций / производительности в обновлениях драйверов.
Бен Ричардс