NVIDIA GeForce GTX 480, часть 2: новые возможности

В первой части обзора графической архитектуры NVIDIA Fermi мы рассмотрели изменения, произошедшие в архитектуре вычислительной части ядра – потоковых мультипроцессоров. Теперь обратимся к ключевым нововведениям в новом продукте компании.

PolyMorph Engine

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

1) Загрузка вершин из общего буфера вершин, получаемого анализом загружаемых из локальной памяти или по шине PCI Express от 3D-движка примитивов, передача их на первичную обработку в потоковый мультипроцессор (SM) и последующая отправка на тесселяцию. На этом этапе определяются координаты вершин в масштабах всей трехмерной сцены и высчитывается коэффициент (степень) тесселяции.
2) Тесселяция: полигоны, сформированные загруженными вершинами, подвергаются тесселяции с определенным ранее коэффициентом, а затем передаются обратно в SM для дополнительной обработки (наложения карты смещения, отсечения перекрытых вершин и т.д.).
3) Преобразование порта просмотра (viewport) – коррекция перспективы и другие операции над участком сцены, видимым в конкретном кадре.
4) Установка атрибутов – преобразование полученных на предыдущих этапах свойств вершин в уравнения для дальнейшей их обработки пиксельными, вершинными и геометрическими шейдерами на SM.
5) Выгрузка потока – отправка полученного результата в буфер для того, чтобы его можно было повторно или дополнительно обработать без необходимости проходить все стадии заново.

Очевидно, что наиболее интересным этапом в работе PolyMorph Engine является тесселяция. Эта техника не нова, и, в общем-то, о ней уже много говорилось как сравнительно недавно (с выходом архитектуры ATI Radeon HD 2xxx в 2007 году), так и значительно раньше (в компьютерной графике для кинематографа это один из основных методов достижения высокой геометрической подробности моделей уже многие годы). Однако, поскольку DirectX 11 и OpenGL 3.0 ставят эту процедуру «во главу угла» в обработке моделей и она все активнее начинает использоваться в реальных игровых движках, вкратце опишем, что же происходит.

Каким образом можно добиться высокой детализации объекта? Обычно – вручную создать многополигональную модель. Однако это крайне неудобно: во-первых, дизайнеру придется затратить много времени на ее создание, во-вторых, она потребует высоких затрат производительности на обработку и анимацию, в-третьих, дополнительно придется создавать модели меньшей детализации для рендеринга удаленных объектов, которым высокая подробность ни к чему.

Современные 3D-движки в большинстве случаев выводят несколько десятков, в крайнем случае – сотен тысяч вершин одновременно, в то время как в кинематографе CG характеризуется значениями в десятки миллионов. Одно дело, когда речь идет о небольшом размере поверхности, на которую выводится изображение (т.е. диагонали монитора), тогда малая детализация скрадывается неразборчивостью мелких объектов. Однако на сегодняшний день диагонали 27–30” для игровых ПК – вовсе не фантастика, не говоря уж об игровых приставках, подключаемых к телевизорам с диагоналями 54–60”, на которых можно разглядеть каждую недоработку дизайнера. Следовательно, нужно повышать количество отображаемых полигонов, чтобы картинка не казалось «мыльной», «угловатой» и т.п., но грубым методом создания более детальных моделей сделать такое невозможно, так как это обрушит быстродействие любого ПК до неприемлемого уровня, да и времени на разработку потребует очень много. Тут и приходит на помощь тесселяция.

Базовая модель, она же после тесселяции и после наложения карты смещений

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

Принцип работы карты смещения

 

Однако сама по себе тесселяция не может полностью удовлетворить нужды дизайнеров в повышении детализации, поскольку сложный рельеф она сгенерировать не в состоянии. Пожалуй, наиболее применима чистая тесселяция без дополнительной обработки лишь при рендеринге воды, а с геометрически развитыми моделями нужен другой подход. Тут на помощь приходят карты смещений – техника, развивающая давно известный бамп-маппинг. Карта смещения (displacement map) – это фактически текстура, в которой вместо цветовых характеристик пикселей содержатся относительные координаты вершин (углубление или возвышение). Наложив ее на подвергнутый тесселяции объект, можно получить на нем сложный рельеф. Преимущество этой методики над сходными методами (наложением карт нормалей, параллакс-маппинга) в том, что обработке подвергаются именно вершины, а не пиксели текстур, которые затем на них накладываются, что дает возможность намного точнее просчитывать перекрытие пикселей и отбрасывать невидимые, добиваться более качественных теней и реалистичного освещения.

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

В архитектуре NVIDIA Fermi эффективности тесселяции уделено большое внимание. Поскольку каждый мультипроцессор оснащается 64 КБ кэша, который можно сконфигурировать как комбинации 16 КБ L1+48 КБ L2 и наоборот, появляется возможность хранить все данные о геометрии прямо на GPU, без необходимости выгрузки их в DRAM и считывания их оттуда. Вместе с появлением поддержки аппаратной рекурсии и полной точности в 32-битной обработке получается, что GPU способен радикально увеличить быстродействие при генерировании дополнительных вершин из малополигональных моделей. Также кэши очень благотворно сказываются на быстродействии в трассировке лучей, поскольку бесконечное число отражений, преломлений и т.п., растущее в геометрической прогрессии при увеличении числа источников света и детализации объектов сцены, требует огромного количества случайных обращений к памяти, чего контроллеры в GPU очень не любят. Емкий кэш радикально снижает обмен данными с DRAM на этапе обработки и увеличивает производительность настолько, что NVIDIA уже предлагает разработчикам игр интегрировать свой движок Optix для создания фотореалистичных скриншотов в режиме галереи (например, в гоночных симуляторах).

 

 

Глубокие усовершенствования коснулись также планировки потоков, отправляемых на обработку в SM: если ранее он мог исполнять только один варп потоков (минимальная единица, в которую объединяются потоки с однородными операциями над данными), то теперь планировщик может отправить на обработку в один SM сразу два разных варпа, выбрав их из очереди инструкций, полученной от GigaThread Engine. Благодаря этой возможности ресурсы GPU используются более эффективно.

Новый режим сглаживания

В Fermi реализован еще более эффективный режим сглаживания краев объектов, названный 32x CSAA (Coverage Sample Antialiasing). Фактически это мультисэмплинг по 8 образцам (8x MSAA) с дополнительным Coverage Sampling по 24 образцам. Этот режим значительно повышает эффективность сглаживания мелких перекрывающихся малополигональных текстурированных объектов – травы, листвы деревьев, осколков и т.п. Также GeForce GTX 4xx получили более «умный» алгоритм работы с прозрачными текстурами – Transparent Multisampling, который позволяет избежать частых артефактов при сглаживании всевозможных окон, проволочных сеток, силовых полей и т.п. При этом, поскольку данные по перекрытию объектов и их краям, используемые в CSAA, занимают мало места, в большинстве случаев производительность в режиме 32x CSAA не должна сильно отличаться от обычного 8x MSAA.

 

 

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

NVIDIA 3D Vision Surround

 

 

Калифорнийский вендор отвечает на последний козырь канадского соперника – технологию ATI Eyefinity – собственной аналогичной разработкой. Видеокарты Fermi позволяют не только сконфигурировать массив из трех мониторов для вывода трехмерной сцены, но и делать это в режиме стереоскопического рендеринга. Единственная оговорка: нынешние модели все же поддерживают одновременный вывод изображения лишь на два монитора, потому для 3D Vision Surround понадобится массив SLI. Отметим, что поддержка стереоскопии не является обязательным требованием: возможна работа и с тремя обычными мониторами. Также появилась функция Bezel Correction, позволяющая скорректировать выводимое изображение для уменьшения дискомфорта от наличия рамок мониторов. Ее суть состоит в том, что часть картинки просто выводится «за пределы монитора», таким образом создается впечатление, что игрок смотрит сквозь окно с рамой, и общая сцена не разрывается на части.

Справедливости ради отметим, что в данном случае идет речь не о новшестве в архитектуре Fermi, а о дальнейшем совершенствовании драйвера NVIDIA, однако общее усиление GPU GF100 в значительной мере должно увеличить комфорт при игре с использованием 3D Vision. Что касается сравнения с ATI Eyefinity, то технология канадской компании поддерживает работу с шестью мониторами против трех у NVIDIA, однако не работает в стереоскопическом режиме и требует использования мониторов с разъемом DisplayPort, которых, мягко говоря, немного.

Новшества в CUDA

Рассматривая современные графические архитектуры, все время приходишь к мысли, что первоначальная идея о гетерогенных вычислениях, в которых архитектурно сложные и «умные» CPU будут отвечать за исполнение сложных алгоритмов, а простые, но быстрые GPU – за скоростные вычисления множества потоков, постепенно перерождается, причем неожиданным образом: графические процессоры становятся все сложнее и сложнее и вскоре не будут уступать по своим возможностям центральным. Судите сами: на GPU появились отдельные блоки ALU и FPU, кэши, планировщики потоков, возможность перестроения очереди инструкций и оптимизации конвейера, аппаратная рекурсия и многие другие атрибуты «серьезных» процессорных архитектур. Intel Larrabee обещала быть скорее сверхмногоядерным CPU, чем GPU, а в итоге множество ее черт есть уже в NVIDIA Fermi.

 

Новая архитектура поддерживает все четыре метода округления по стандарту IEEE 754-2008 (до ближайшего ненулевого значения, до нуля, до положительной и отрицательной бесконечностей), что делает ее полностью подходящей для научных вычислений с 32-битной точностью. Ранее платформа NVIDIA лишь условно подходила для использования GPGPU в научных и медицинских целях, поскольку предыдущие поколения GPU все значения машинного нуля (числа в промежутке между нулем и минимальным ненулевым значением в поддерживаемой системе исчисления) попросту сбрасывали на нуль. Естественно, в задачах, требующих высокой точности результатов, где третий-пятый порядок после запятой – не пренебрежимая мелочь, CUDA была недостаточно функциональной платформой. Теперь же Fermi позволяет сохранять эти значения, причем они могут обрабатываться с помощью блоков специальной функциональности (SFU) с использованием инструкций Fused Multiply-Add за один такт без отсечения разрядов, в то время как на CPU обработка машинного нуля зачастую перекладывается на плечи ПО и требует нескольких тысяч тактов, а в GPU предыдущих поколений 32-битные вычисления использовали только инструкции MAD, в которых на промежуточном этапе между умножением и сложением часть разрядов отбрасывалась.

Также кардинально переработан механизм вычислений с двойной точностью, теперь каждый мультипроцессор может обработать до 16 операций сложения-умножения с двойной точностью за такт, т.е. до 256 операций за такт на полнофункциональное ядро GF100.

Одно из важнейших новшеств с точки зрения использования новой архитектуры для вычислений – введение поддержки коррекции ошибок ECC. Коды SECDED позволяют определять и исправлять однобитные ошибки и определять и сообщать обо всех двухбитных и многих многобитных ошибках, что значительно повышает надежность вычислений и достоверность получаемых результатов. ECC поддерживается на уровне данных, хранимых в регистровых файлах, общей памяти и кэшах мультипроцессоров, и DRAM, также в наличии CRC для данных, передаваемых по шинам PCI Express и GDDR5.

Новое поколение GigaThread Engine способно запускать на исполнение сразу несколько так называемых ядер CUDA. Упрощенно, речь идет о следующей иерархии: отдельные вычислительные потоки CUDA объединяются в блоки, те – в сетки (CUDA Grid), а сетки, в свою очередь, исполняются в рамках ядра CUDA (CUDA Kernel). Речь идет об однородных инструкциях над разными данными (SIMD), типичный пример – симуляция воды, симуляция взаимодействия упругих или твердых тел и т.д. исполняется над большим числом объектов и частиц по одним и тем же алгоритмам. Уточним, что блоки (CUDA Blocks) – это не то же самое, что упоминавшиеся выше варпы (warps) – минимальные «пучки» потоков, которые планировщик может отправить на исполнение в мультипроцессор.

 

Итак, ранее на всем GPU одновременно можно было запустить лишь одно ядро CUDA, а значит, что при небольшом числе генерируемых им потоков могла сложиться ситуация, когда работой загружены не все мультипроцессоры. Графику параллельно обрабатывать GPU не может, поскольку это другой контекст, другие данные из памяти и другие инструкции, и получается, что часть чипа просто простаивает. Теперь же планировщик может запустить несколько ядер параллельно, причем возможно перестроение очереди запуска для оптимальной загрузки всех мультипроцессоров. Следовательно, обработка будет проходить намного быстрее, на практике это означает, например, значительное снижение потерь производительности при работе PhysX с разнородными эффектами (жидкостью, взаимодействиями тел, тканью и т.д.).

Наконец, еще один аспект платформы CUDA, пришедший вместе с Fermi – удобство разработки ПО. Во-первых, теперь используется общее адресное пространство памяти для CUDA, что позволяет NVIDIA говорить о полной поддержке объектно-ориентированных языков программирования C и С++. Ранее разработчику нужно было четко указывать адреса в памяти, откуда будут считываться и куда будут сохраняться локальные данные отдельного потока, общие данные блока потоков в буфере и глобальные данные всего ядра, однако в написанных на С++ программах эти адреса зачастую определяются указателями и выделяются динамически в процессе работы, а не при компилировании. В Fermi встроенные в каждый мультипроцессор блоки Load/Store, отвечающие за адресацию, способны работать с общим адресным пространством, включающим в себя и локальную, и общую, и глобальную память, и «понимают» не только точные адреса, но и указатели. Этот шаг навстречу разработчикам позволяет надеяться, что ПО, использующего CUDA, станет значительно больше, поскольку усилий на написание кода теперь потребуется меньше.

 

 

Наконец, нельзя не отметить появление крайне полезного инструментария NVIDIA Nexus – надстройки для Microsoft Visual Studio, позволяющего писать код, отслеживать ошибки, компилировать и тестировать ПО в этой среде разработки с использованием привычных инструментов.

В третьей части нашего обзора графической архитектуры Fermi мы перейдем от теории к практике и рассмотрим новую флагманскую видеокарту NVIDIA – GeForce GTX 480.