Как я уже писал в прошлый раз, становится какой-то дурной традицией переделывать тест умножения матриц каждые несколько месяцев.
В этот раз причиной для тестов стало появление у меня в доступности видеокарты NVidia GTX280, что позволило протестировать два момента:
- Производительность умножения матриц с одинарной точностью (SGEMM) на новом быстром оборудовании.
- Производительность умножения матриц с двойной точностью (DGEMM).
Участники забега
Hardware
- Intel Core2Quad 9300, на частоте 3GHz, память DDR2 PC6400 4-4-4-12
- NVidia GeForce GTX280 на штатной частоте
- Windows Vista Ultimate x64
- Goto BLAS 1.26 (использовалась под Cygwin, 32-битный режим)
- NVidia CUDA 2.1 beta (64-битная версия)
Методика тестирования
Методика совершенно незатейлива: берем квадратные матрицы, достаточно большого размера, пропорционального 1024 (для таких матриц получается максимальное быстродействие), инициализируем случайными данными, перемножаем библиотечным вызовом (SGEMM/DGEMM или аналогами), определяем затраченное на умножение время, считаем гигафлопсы. Перед забегом проверяем правильность работы перемножая маленькие матрицы (8x8) и проверяя глазом корректность результата.
В случае видеокарты необходимо учитывать, что отдельное время требуется на пересылку данных в видеокарту и получение обратно результата, поэтому для CUDA считалось два быстродействия:
- Чистое быстродействие - без учета времени на пересылку данных.
- Полное быстродействие - с учетом времени на ввод-вывод.
Результаты: одинарная точность
| Производительность умножения матриц (SGEMM: одинарная точность), GFLOP/s | ||||
|---|---|---|---|---|
| Описание теста | размер задачи | |||
| 1024 | 2048 | 4096 | 6144 | |
| Goto BLAS 1.26 | 74.1 | 76.3 | 86.4 | 86.9 |
| NVidia GTX280, CUDA 2.1 beta, чистое время вычислений | 350 | 366 | 370 | 372 |
| NVidia GTX280, CUDA 2.1 beta, вычисления+ввод-вывод | 168 | 238 | 288 | 313 |
| Производительность 8800GTX, для сравнения | ||||
| NVidia 8800GTX, CUDA 2.0 beta, чистое время вычислений | 202 | 204 | 205 | - |
| NVidia 8800GTX, CUDA 2.0 beta, вычисления+ввод-вывод | 151 | 177 | 190 | - |
В сравнении с предыдущей бенчмаркой скорость вычисления на CPU чуть-чуть (на пару процентов) упала, я немного грешу на Висту (предыдущие тесты были на WinXP x64), но изменение в пределах допустимой погрешности.
Чистая скорость вычислений на GTX280 соответствует ожиданиям: ожидали 370-375 Gflop/s, столько и получили. Это, конечно, очень далеко от креативных 900Gflop/s, которые рассчитываются исходя из предположения, что все вычислительные блоки считают MAD и ничего не ждут, но общее соотношение реального быстродействия к "креативному" примерно такое же, какое было на G80, может быть чуть хуже.
Полное (c учетом пересылки данных в/из видеокарты) быстродействие выросло не так сильно: для матрицы 1024x1024 роста практически нет, для матрицы 4096x4096 полное быстродействие выросло в 1.65 раза, а чистое - в 1.8 раза. Эффект неудивительный, ведь скорость PCIe интерфейса от скорости вычислений на карте не зависит.
Необходимо отметить, что 8800GTX не поддерживает асинхронного режима работы, а в более новых картах при работе с небольшими матрицами задержки на пересылку данных вполне можно спрятать: пока обсчитывается один набор данных, можно загружать данные для следующего или получать результаты предыдущего. Конечно, это имеет смысл, если наборов данных более одного, но если он всего один, то и скорость вычисления на CPU должна устроить.
Невысокая скорость CPU на маленьких задачах объясняется, скорее всего, невысоким разрешением использованного таймера (порядка 10ms).
Результаты: двойная точность
Двойная точность вызывала у меня особый интерес: формальные характеристики G200 по двойной точности были относительно невысокими и если бы отношение реального быстродействия к заявленным "креативным" цифрам было бы таким же, как для одинарной точности, то для многих задач быстрее было бы посчитать их на CPU. Действительность оказалась заметно лучше ожиданий:
| Производительность умножения матриц (DGEMM: двойная точность), GFLOP/s | |||
|---|---|---|---|
| Описание теста | размер задачи | ||
| 1024 | 2048 | 4096 | |
| Goto BLAS 1.26 | 34.6 | 42.3 | 42.9 |
| NVidia GTX280, CUDA 2.1 beta, чистое время вычислений | 73 | 74.6 | 75.3 |
| NVidia GTX280, CUDA 2.1 beta, вычисления+ввод-вывод | 46.4 | 57.4 | 65.8 |
Как видим, не все так плохо: на двойной точности GTX280 более чем в полтора раза быстрее 4-ядерного десктопного процессора, даже с учетом пересылки данных. Если же затраты на пересылку спрятать (вычислений много), то видеокарта быстрее центрального процессора почти вдвое.
Из общих соображений, производительность на вычислениях с двойной точностью определяется не bandwidth памяти, а именно производительностью вычислителя: в сравнении с одинарной точностью быстродействие упало более чем вчетверо, а объем данных вырос ровно вдвое. Таким образом, выигрыша на вычислениях с бОльшей арифметической интенсивностью, в отличие от случая одинарной точности, ожидать не следует.
Обсуждение результатов и выводы
Полученные результаты можно рассматривать с трех разных точек зрения:
- какова цена десктопного гигафлопса (метрика довольно сомнительная, но зато это одна цифра);
- масштабируемость десктопных решений;
- как это все масштабируется на относительно небольшие серверы.
Цена десктопного гигафлопса
Для десктопных решений (которые, собственно, и тестировались) "экономика гигафлопса" выглядит следующим образом:
- Гигафлопс одинарной точности стоит:
- $1.3 если его покупать в виде NVidia Geforce GTX280
- $1.0 в виде NVidia Geforce GTX260 (приблизительная оценка, исходя из частоты и количества
- $2.9 в виде Intel Core2Quad Q9300 (разогнанный до 3GHZ, что он легко позволяет).
- Гигафлопс двойной точности стоит:
- $6.3 в виде GTX280
- $4.8 в виде GTX260 (грубая оценка, исходя из частоты и количества процессоров)
- $5.8 в виде Core2Quad
Как любая однозначая метрика, цена гигафлопса на самом деле ничего не характеризует, а жизнь гораздо сложнее. Например, собрать работающий компьютер вообще без CPU не получится, а значит нужно считать прирост производительности, получаемый от замены самого дешевого процессора на рассматриваемый оптимальный по стоимости гигафлопса.
Вместе с тем, данный показатель считался и в тесте годовалой давности, можно видеть что цена GPU-гигафлопса упала впятеро (в том числе и за счет оптимизации программ), а CPU-гигафлопс подешевел за год втрое (вклад программ тоже есть, но меньший).
Вместе с тем, простые прикидки показывают, что разрыв между одним CPU и одним GPU по производительности с одинарной точностью за последний год только вырос (и Core i7 положение исправит не сильно), а отсутствие вычислений с двойной точностью за это же время было вылечено. По двойной точности разрыв не настолько велик, чтобы был смысл перетаскивать вычисления на GPU, но гибридные схемы (приближенный расчет с одинарной точностью и уточнение на двойной) стали гораздо интереснее: их можно делать не только на комбинации CPU/GPU как всего полгода назад, но и целиком на видеопроцессоре.
Увеличение разрыва по быстродействию в очень существенной степени связано с прогрессом в софтописании: архитектура новая, чтобы получить разумную производительность понадобилось время на освоение.
Нельзя забывать, что десктопная система допускает легкое и недорогое масштабирование еще втрое (путем добавления видеокарт). Да, не всякая задача такое допускает, но если у вас много независимых не очень крупных расчетов, то за $2000-2500 можно получить на столе чуть более реального терафлопса с одинарной точностью и более 200 GFLOP/s с двойной. Индустриальные решения (Quadro и Tesla) дороже, но и они более чем конкурентны по отношению цена/производительность. Дело лишь за программами.