NVIDIA GeForce GTX 480, часть 1: архитектура Fermi

Сказать, что выхода нового поколения графических ядер от NVIDIA ждали – значит, ничего не сказать. Компания, многие годы поддерживавшая бешеный темп разработки и выпуска GPU (фактически выход новых флагманов раз в два квартала и ежегодное обновление архитектуры были стандартом со времен Riva TNT) и лишь один раз «провалившая задание» с GeForce 5800, сделала последний мощный рывок в 2006-м, представив GeForce 8 (G80). Заложенные в G80 возможности оказались столь впечатляющи, что продукты на основе этого поколения чипов до сих пор вполне конкурентоспособны в средне-бюджетном ценовом диапазоне (GeForce GTS 250) – спустя почти четыре года! Однако конкуренты из ATI не сидели сложа руки.

Так что, даже несмотря на то что NVIDIA удавалось удерживать позиции путем обновления архитектуры по принципу «чуть больше всего» (чип GT200) и сохранять формальное лидерство по производительности за счет монстроподобных двухчиповых решений аж до выхода Radeon HD 5970, достаточно давно в среде ИТ-энтузиастов, а иногда и в профильной прессе велись разговоры о том, что, мол, «NVIDIA уже не та; соревнование за технологическое лидерство давно проиграно; калифорнийцы мечтают о своем х86-процессоре и т.д. и т.п.». Слухи о Fermi ходили весь 2009 год, в том числе и по поводу сроков релиза – под конец истории регулярные переносы даты анонса уже стали и вправду смущать: целые полгода форы ATI в качестве безраздельного лидера – это очень серьезно. И вот наконец, в нашей Тестовой лаборатории – референсный графический адаптер GeForce GTX 480, созданный на основе чипа GF100, флагманского решения NVIDIA на сегодняшний день. Пока мы заканчиваем практическое тестирование Fermi, предлагаем ознакомиться с теоретической частью материала об этом революционном с точки зрения архитектуры графическом чипе NVIDIA.

Архитектура Fermi

Ядро видеокарты с каждым годом приобретает все больше возможностей для проведения различных расчетов, в том числе не связанных напрямую с изображением. В 1999 году на GeForce 256 впервые внедрили аппаратную обработку трансформации и освещения (T&L, Transform & Lighting) – именно это поколение впервые получило обозначение GPU, то есть «блок обработки графики». В 2001-м с выходом GeForce 3 появилась возможность работы с программируемыми шейдерами – то, без чего дальнейшее развитие игрового 3D было практически невозможно. Наконец, переработка архитектуры шейдерных блоков в GeForce 8 (унифицированные вычислительные блоки вместо разделения на узкопрофильные пиксельные и вертексные) не только позволила существенно гибче использовать вычислительные мощности в традиционных задачах, но и сделала гораздо более реалистичным процесс выполнения иных, «неграфических» расчетов силами GPU.

 

Идеология «GPU Computing», положенная в основу GeForce 8 (G80), нашла свое развитие в GeForce 200 (GT200): в частности, появилась поддержка двойной точности при операциях с плавающей точкой – требование, необходимое для многих научных вычислений. И Fermi при всей архитектурной непохожести на предшественников в этом аспекте продолжает движение запланированным курсом, являясь, по терминологии NVIDIA, третьим поколением «потоковых мультипроцессоров» (SM, streaming multiprocessor) – все больше «общих вычислений», все ближе по большому счету к CPU-функциональности…

Концептуальных задач при создании нового GPU разработчики ставили четыре: «выдающаяся производительность в играх», «первосортное качество изображения», «геометрический реализм на уровне кино» и «создание революционной вычислительной архитектуры для игр». Что стоит за этими маркетинговыми формулировками – мы рассмотрим позже, а пока более интересны технические аспекты Fermi. С точки зрения инженерных задач, разрабатывая GF100, проектировщики внесли следующие ключевые изменения в архитектуру «потокового мультипроцессора», в основном по требованиям CUDA-программистов:

  1. Улучшили производительность в операциях с двойной точностью: в сравнении со средним настольным CPU скорость работы в FP-задачах у GPU примерно в десять раз выше, но некоторые приложения требовали аналогичного уровня производительности и при двойной точности;
  2. Внедрили поддержку памяти с коррекцией ошибок (ECC), что позволяет расширить профессиональное применение: таким образом повышается надежность работы многочисленных GPU-инсталляций в дата-центрах, а также обеспечивается защита от ошибок памяти в критических к точности приложениях финансовой и медицинской сфер;
  3. Создали иерархию кэш-памяти, так как некоторые алгоритмы паралеллизации неспособны использовать общую память GPU: теперь в архитектуре имеются выделенные L1- и L2-кэши;
  4. Увеличили объем общей памяти – многие программисты, использующие CUDA, просили расширить общую память свыше имевшихся 16 КБ для того, чтобы их приложения работали быстрее;
  5. Ускорили контекстное переключение между режимами обработки графики и произведения прочих расчетов, а также увеличили скорость операций записи-чтения-изменения для параллельных алгоритмов.

В итоге ключевыми архитектурными особенностями Fermi являются:

  • Третье поколение потокового мультипроцессора (SM):
    — 32 ядра CUDA на SM, вчетверо больше, чем у GT200;
    — восьмикратный прирост производительности в FP-операциях двойной точности в сравнении с предсшественником;
    — два блока Warp Scheduler на SM вместо одного;
    — 64 КБ ОЗУ с конфигурируемым разделением на общую память и L1-кэш.
  • Второе поколение набора инструкций параллельного выполнения потоков (Parallel Thread Execution, PTX 2.0):
    — унифицированное адресное пространство с полной поддержкой С++;
    — оптимизация для OpenCL и DirectCompute;
    — полная 32- и 64-битная точность в соответствии с IEEE 754-2008;
    — инструкции доступа к памяти для поддержки перехода на 64-битную адресацию;
    — улучшенная производительность предсказаний.
  • Улучшенная подсистема памяти:
    — иерархия NVIDIA Parallel DataCache с конфигурируемым L1-кэшем и общим L2;
    — поддержка ECC, впервые на GPU;
    — существенно увеличенная производительность операций чтения и записи в память.
  • Движок NVIDIA GigaThread:
    — десятикратное ускорение процедуры контекстного переключения;
    — параллельное выполнение кернелов;
    — непоследовательное исполнение потоков.

Структура графического ядра GF100

Первой практической имплементацией архитектуры Fermi стал, вполне традиционно, графический чип класса hi-end под кодовым названием GF100. Такой индекс неслучаен: «GF» означает «Graphics» и «Fermi», то есть графическое решение на основе Fermi, а цифровая часть, по мнению NVIDIA, подчеркивает позиционирование данного GPU наверху линейки. С применением GF100 на данный момент анонсировано два видеоадаптера: GeForce GTX 470 и GeForce GTX480, о которых более подробно будет рассказано во второй части материала.

Как и предшественники, GF100 организован в виде масштабируемого массива блоков: «кластеров обработки графики» (GPC), потоковых мультипроцессоров (SM) и контроллеров памяти, плюс интерфейс PCI-Express, планировщик GigaThread Engine, 48 блоков ROP и общий L2-кэш. В максимальной на данный момент конфигурации GF100 состоит из четырех GPC (по четыре SM в каждом) и шести контроллеров памяти, однако анонсированные видеокарты уже предполагают несколько урезанные характеристики, что однозначно намекает на достаточно скорый выход нового флагмана.

Команды от CPU поступают к GF100 через интерфейс шины PCI-Express. Глобальный планировщик GigaThread Engine собирает данные из оперативной памяти и копирует их в кадровый буфер графического адаптера через шесть 64-битных контроллеров памяти (таким образом, общая ширина шины ОЗУ у GF100 составляет 384 бита, но поддержка GDDR5 обеспечивает достаточную пропускную способность). Затем GigaThread создает и распределяет блоки потоков на потоковые мультипроцессоры (SM). В свою очередь, отдельные SM раздают потоки группами по 32 штуки (такая группа именуется «варпом») для обработки CUDA-процессорами и прочими блоками исполнения. Также GigaThread перераспределяет нагрузку на SM-ы в процессе обработки изображения, например на стадиях тесселяции и растеризации.

Основой вычислительной мощи GF100 являются 512 универсальных процессоров (именуемых «ядрами CUDA» по терминологии разработчика), состоящих из ALU- и FPU-блока и способных обрабатывать пиксельные, вершинные, геометрические или «общевычислительные» программы. По сравнению с предыдущим поколением главными изменениями стала поддержка полной 32-битной точности и исполнение 64-битных инструкций блоком ALU, а также поддержка блоком FPU стандарта IEEE 754-2008, что позволяет выполнять совмещенные операции умножения-сложения при вычислениях с одинарной или двойной точностью, тем самым снижая количество ошибок рендеринга в некоторых случаях.
Универсальные процессоры организованы в потоковые мультипроцессоры по 32 CUDA-ядра в каждом. Количество ядер на SM вчетверо больше, чем у GT200, но при этом общее количество самих SM уменьшилось – поэтому в итоге по данному параметру GF100 лишь чуть более чем вдвое опережает предшественника – 512 ядер против 240. Увеличение плотности CUDA-ядер не стало единственной модернизацией в структуре потокового мультипроцессора. Текстурные модули переместились в структуру SM, хотя раньше были выполнены в виде отдельных блоков – теперь же каждый SM имеет по 4 «текстурника» с общим кэшем. Также, в отличие от GT200, каждый SM содержит по два планировщика варпов и диспетчера инструкций, таким образом позволяя одновременно выполнять два варпа на одном мультипроцессоре. Еще одним элементом SM являются четыре модуля специальных функций (Special Function Unit, SFU), выполняющие операции по вычислению синуса, косинуса, квадратного корня и т.п. и имеющие собственный конвейер, отделенный от блока диспетчера. Наконец, вместо 16-килобайтной общей памяти в структуре SM теперь имеется 64 КБ, разделяемой по необходимости на общую память и традиционный L1-кэш, что позволяет ускорить работу большинства программ – как использующих общую память (за счет увеличения объема последней), так и не использующих (за счет внедрения L1-кэша, ранее отсутствовавшего в архитектуре GPU).

Потоковые мультипроцессоры, в свою очередь, объединены в четыре «кластера обработки графики» (Graphics Processing Cluster, GPC) – базовые архитектурные блоки GF100 и одна из ключевых инноваций этого поколения GPU. Каждый GPC включает в себя не только четыре SM, но также масштабируемые движок растеризации (для установки треугольников, растеризации и исключения невидимых поверхностей) и движки PolyMorph (ответственные за тесселяцию и выборку вершинных атрибутов). На каждый GPC приходится по одному Raster Engine, а количество PolyMorph Engine определяется количеством SM – то есть, как правило, их четыре штуки на один кластер. Именно возможности GF100 по обработке геометрии, определяемые Raster Engine и PolyMorph, играют ключевую роль в приближении к заявленному NVIDIA идеалу «игр с реалистичностью кинематографа».

Фактически GPC по функциональности является завершенным GPU за вычетом отсутствующих блоков ROP, которые выполняют операции блендинга, полноэкранного сглаживания и атомарные операции с памятью. У GF100 имеется 48 таких блоков, объединенных в наборы по 8 штук и «привязанных» к контроллерам памяти и L2-кэшу. Наличие последнего также является нововведением – как уже было отмечено, создание внутри GPU традиционной иерархии кэш-памяти позволяет «упростить жизнь» программистам, ускорив выполнение многих программ. Очевидно, что в дальнейшем NVIDIA представит более доступные решения семейства Fermi, которые будут отличаться от GF100 уменьшенным количеством GPC при сохранении общей архитектуры.

Во второй части материала о GeForce GTX 480 и Fermi в целом мы рассмотрим, как вышеописанные архитектурные решения повлияли на возможности GPU. В частности, речь пойдет о значительном улучшении обработки геометрии за счет тесселяции и карт смещения, новых методах полноэкранного сглаживания, расширении возможностей организации вычислений (включая обсчет трассировки лучей), а также о NVIDIA 3D Vision Surround – технологии, развивающей идею конкурента, т.е. ATI Eyefinity.