Умножение матриц, серия 4: NVidia G80, CUDA, CuBLAS и RapidMind

GPGPU или зачем все эти упражнения

Все предыдущие
и более ранние мои упражнения были сделаны в качестве «подхода к снаряду», нужна
была baseline для более интересной задачи: вычислений общего назначения на видеокарте.

Эта тема в последние год-полтора (а особенно, в последние полгода) очень сильно нагрелась.
В то же время, в варианте от NVidia hardware и софт общедоступны, покупаешь видеокарту
и развлекаешься.

Приборы и материалы: NVidia CUDA и прочие
Настоящий общедоступный сдвиг произошел меньше месяца назад: 6 февраля 2006 г. вышла
вторая версия NVidia CUDA Toolkit, она же первая публичная (и первая более-менее работающая), она же
версия 0.8.
Эта версия доступна всем желающим без
подписания NDA, следовательно результаты тестов можно открыто публиковать.

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

Рассматривались три доступных умножителя матриц:

  1. SGEMM в составе библиотеки CUBLAS.
  2. Тестовый пример от NVidia, который очень подробно разобран в документации.
  3. Реализация SGEMM от RapidMind.

Сравнивалось все с результатами вычислений на доступных мне компьютерах общего назначения:

  1. Dual Opteron 275 (2.2 Ghz) - долгое время это был "предпоследний процессор в линейке"
    т.е. наиболее разумный выбор по цена/качество.
  2. Dual Xeon 5140 - текущий оптимум по цена/производительность.

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

  • Вычислитель на G80: NVidia 8800GTX + современная недорогая обвязка (процессор,
    память): $1200-1300, половину суммы составляет видеокарта.
  • Вычислитель на Dual Opteron 275: $1200-1300, половину стоимости составляют
    два процессора.
  • Вычислитель на Dual Xeon 5140: $1600-1700 из которых около 1000 за два процессора.

Xeon - существенно дороже, но как мы помним по прошлым тестам, он примерно в 1.6 раза быстрее
на вычислениях.

Результаты тестов

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

  • Загрузка данных в видеопамять
  • Запуск вычислительного модуля, исполняемого GPU
  • Выгрузка данных в основную память компьютера

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

Быстродействие на перемножении матриц (MFLOP/s)
Платформа размер задачи
1024 2048 4096
Вычисления на CPU
2xOpteron 275, Goto BLASsingle precision, 4 threads 23 091 28 971 30 272
2xXeon 5140, Goto BLASsingle precision, 4 threads 26 512 45 935 47 556
NVidia G8800GTX: Чистое время вычислений
RapidMind 2.0b3 109 653 -* -*
пример из CUDA toolkit 46 403 46 562 46 299
cuBLAS SGEMM 97 713 99 890 98 738
NVidia G8800GTX: Вычисления + загрузка-выгрузка данных в видеокарту
RapidMind 2.0b3 33 314 -* -*
пример из CUDA toolkit + IO 25 230 35 911 40 879
NVidia G8800GTX, cuBLAS SGEMM 58 703 73 670 83 473
* — Стандартный пример от RapidMind ограничен матрицами 1020x1020

Обсуждение результатов
RapidMind
Пример от RapidMind не использует аппаратных особенностей G80 и должен работать
на любой DX9-видеокарте. Используется операция MAD (Multiply-Add) над векторными
(4 компонента) операциями. По всей видимости, MAD работает, получающаяся производительность
весьма вкусная. К несчастью, пример плохо масштабируется, программировать в терминах
4-векторов очень мучительно. А убивает все скорость копирования данных из видеокарты:
стандартные средства DX9 очень медленные и неудобные.
Пример от NVIdia
Умножение матриц в примере от NVidia сделано с большой претензией: блоки данных
копируются в сверхбыструю shared-memory, где и умножаются. Однако shared-памяти мало,
16 килобайт на мультпроцессор (всего, соответственно, 256kb полмегабайта, исправлено 01.10.07) и весь пар уходит
в свисток: синхронизацию всех тредов. Результат получается хуже, чем у более сложного
кода для CuBLAS.
CuBLAS
Про внутренности CuBLAS неизвестно ничего. По внешним признакам, там нет глупостей
с оптимизацией на кратность матрицы размеру блока в shared memory и прекрасно
сделано копирование данных в(из) видеопамять.
Выводы
На несложной задаче без ручных оптимизаций NVidia G80 делает в 2-3 раза
вычисления на мощных современных CPU (двух двухядерных). Исследования надлежит
продолжать.

Tags: