Умножение матриц, серия 3: Woodcrest против Opteron, ACML против MKL, Goto BLAS против всех

Использованная в предыдущем тестировании библиотека численных методов Intel Math Kernel Library очевидно не является оптимизированной под процессоры AMD. Следовательно, нужно изучать альтернативы.

Альтернатив на сегодня видно три: это библиотека AMD Core Math Library от производителя процессора и две OpenSource библиотеки: Goto BLAS и ATLAS (Automatically Tuned Linear Algebra Software). Их и изучим.

Все бенчмарки были совершенно одинаковыми: заполнялись исходные матрицы (значениями от 0.0 до 1.0), затем вызывалась функция sgemm (для single precision) или dgemm (double), время выполнения которой и измерялось.

Кроме Dual Opteron 275, в руки попал еще сервер Dual Xeon 5140, показалось полезным сравнить две архитектуры.

Все изменения во времени рассчитывались от базового варианта (который оказался самым медленным) - Intel MKL 9.0 на Dual Opteron 275 в "разах" т.е. время исполнения эталонной бенчмарки делилось на время исполнения проверяемой. Это кажется мне более естественным способом, чем расчет процентов изменения (задача А исполняется 100 секунд, задача Б - 40 секунд. Б быстрее на 60% /считаем от большего/ и в 2.5 раза).

Intel MKL

Использовалась та же тестовая программа, что и в предыдущей заметке. Измерялось, естественно, только время исполнения cblas_sgemm/cblas_dgemm. Изучалась CBLAS-версия, компилятор Intel C/C++ Compiler 9.1.
Intel MKL 9.0
Количество потоковразмер задачи
1024 2048 4096 8192
 Single precision
1 thread 0.375 2.95 23.81 201.4
2 threads 0.187 1.47 11.94 101.2
4 threads 0.109 0.859 6.88 52.42
 Double precision
1 thread 0.688 5.59 49.6 398.5
2 threads 0.359 2.83 24.99 200.6
4 threads 0.187 1.422 14.08 110.2
Табличка дана исключительно для полноты картины. Такая же табличка без последней колонки (8192x8192) есть в предыдущей заметке.

Как мы видим, время исполнения практически точно пропорционально кубу размера задачи, для двойной точности чуть хуже (в пределах 10-12%), что может объясняться худшей «степенью кэшируемости» (отношением размера данных к размеру кэша).

Масштабирование для двух threads практически двукратное, для четырех - в пределах 3.5-3.8 (при этом, double precision версия ускоряется лучше).

Другими словами, результаты вполне ожидаемые, некоторые особенности double-precision версии удивляют, но не сильно (объяснение придумать можно).

AMD ACML

Использовалась библиотека ACML версии 3.6.0 для Intel Fortran.

Получившиеся времена исполнения:

AMD ACML 3.6.0
Количество потоковразмер задачи
1024 2048 4096 8192
 Single precision
1 thread 0.311 2.43 19.18 153.12
2 threads 0.162 1.23 9.65 76.57
4 threads 0.084 0.632 4.98 38.95
 Double precision
1 thread 0.655 5.08 40.68 324.7
2 threads 0.332 2.60 20.43 162.9
4 threads 0.174 1.32 10.48 83.33

Результаты достаточно любопытные:

  • На AMD-железе AMD-библиотека существенно быстрее, чем интеловская. Результат ожидавшийся.
  • Масштабируемость с размером задачи строго кубическая, отклонения от теории очень малы. Остается предположить, что Intel MKL плохо знает, как процессоры AMD работают с памятью и чем меньше кэшируемость данных, тем более это заметно.
  • Масштабируемость по числу threads тоже заметно лучше, чем с интеловской библиотекой.
В результате, чем больше задача, тем больше выигрыш: на матрицах 1024x1024 выигрываем в ~1.2 раза для single и в 1.05-1.08 раза для double, а для 8192x8192 и 4 задействованных ядрах выигрыш уже в 1.34(single)-1.32(double) раза.

Результат опять ожидаемый: производитель железа лучше знает, как оптимизировать под это железо.

Goto BLAS

Библиотека Goto BLAS распространяется в исходных кодах для академического использования. Авторы утверждают, что основной оверхед на текущей архитектуре происходит от промахов в TLB и доказывают свое мнение результатами.

После библиотек от вендоров я предполагал, что дальнейшего выигрыша ждать уже не стоит: ACML-версия в 10 раз быстрее написанного руками кода на C. Однако совершенству предела нет:

Goto BLAS
Количество потоковразмер задачи
1024 2048 4096 8192
 Single precision
1 thread 0.304 2.24 17.6 139.8
2 threads 0.156 1.14 8.90 70.22
4 threads 0.093 0.593 4.54 35.6
 Double precision
1 thread 0.57 4.47 35.1 280.9
2 threads 0.304 2.27 17.80 141.1
4 threads 0.172 1.172 9.06 71.45

Все еще лучше, чем у ACML:

  • Масштабируемость по размеру задачи еще ближе к теоретическому N3.
  • Ускорение относительно MKL-версии больше как для маленьких задач (около 1.2) так и для больших (до 1.54 раза для double precision 8192x8192, 4 threads).
Как видим, опенсорсники в очередной раз утерли нос корпорациям. Впрочем, мотивация опенсорсников понятна: затраты на разработку быстро окупаются полуторакратным ускорением работы, а считают ученые много.

ATLAS

ATLAS самонастраивает себя при сборке исходя из размера L2-cache и оптимальных инструкций для исполнения элементарных операций. Тестирование всех имеющихся вариантов происходит при сборке и занимает несколько часов, однако результат того не стоит: результаты бенчмарок очень близки к AMD ACML, за исключением больших задач с двойной точностью, где ATLAS практически догоняет Goto BLAS:
Atlas 3.7.24
Описание тестаразмер задачи
1024 2048 4096 8192
Single precision, 1 thread 0.359 2.48 19.52 152.5
Double precision, 1 thread 0.585 4.48 35.34 283.0

Многопоточные варианты нормально протестировать не удалось: ATLAS сам определяет нужное количество потоков и второй поток запускался только для части вычислений в задаче 8192x8192, а задачи меньшего размера считались в один поток.

Вердикт: вычеркиваем, для изучаемой архитектуры Goto BLAS сильно лучше.

Intel Xeon 5140 (Woodcrest)

Появившиеся во второй половине 2006 года процессоры Intel Xeon 51xx получили очень хорошую «прессу», по результатам всех тестов они на голову превосходят текущие версии AMD Opteron. Имеющийся в хозяйстве сервер на Dual 5130 позволил удостовериться в этом самостоятельно.

Xeon + Intel MKL

Интеловские библиотеки и компиляторы показали на интеловском железе превосходные результаты:
Xeon 5140 + Intel MKL 9.0
Количество потоковразмер задачи
1024 2048 4096 8192
 Single precision
1 thread 0.194 1.54 12.3 98.8
2 threads 0.108 0.781 6.17 49.8
4 threads 0.07 0.399 3.17 26.0
 Double precision
1 thread 0.387 3.06 24.35 194.4
2 threads 0.205 1.55 12.32 97.96
4 threads 0.152 0.842 6.41 51.35

Результаты ошарашивают. Даже если нормировать время исполнения на частоту (т.е. домножить на 1.06), Woodcrest быстрее Opteron в 1.5-2 раза, причем чем больше размер задачи, тем больше выигрыш. Понятно, что часть этого выигрыша — за счет неоптимальной для AMD библиотеки, следовательно нужна еще попытка.

Масштабируемость тоже очень хорошая — близка к теоретической от размера задачи и почти не хуже чем у Goto BLAS на Opteron.

Xeon + Goto BLAS

Использование Goto BLAS дает еще некоторое ускорение относительно MKL:
Xeon 5140 + Goto BLAS
Количество потоковразмер задачи
1024 2048 4096 8192
 Single precision
1 thread 0.165 1.29 10.06 79.92
2 threads 0.106 0.661 5.09 40.22
4 threads 0.081 0.374 2.89 22.58
 Double precision
1 thread 0.331 2.58 20.36 161.8
2 threads 0.175 1.318 10.29 81.36
4 threads 0.118 0.776 5.94 46.39

Однако выигрывает Intel существенно меньше, чем AMD:

  • Для небольших задач выигрыш относительно MKL очень разный, от 0.8 до 1.2 раза. Времена исполнения этих задач минимальны, обращать внимания на разницу не нужно.
  • Для задач размера 4096-8192 выигрыш не превышает 1.15 раза, а для 4-поточных вариантов еще меньше, 1.04-1.08. Похоже, что уперлись в память.
  • Сравнивая с Opteron + GotoBLAS, видим что для 4-поточных задач выигрыш (с поправкой на частоту) порядка 1.45 раза для больших задач. Для 1-2 поточных выигрыш составляет 1.6-1.65 раза.

Woodcrest: Выводы

  • Intel очень сильно выступил с Woodcrest. Ускорение составляет порядка 60% для 1-2 поточных задач и чуть меньше для 4-поточных.

    Текущей линейке Opteron расти практически некуда (с Opteron 275-го можно апгрейдиться до 285-й модели, что даст 18-%-й рост частоты) т.е. текущие продаваемые варианты - тупиковые. Ждем нового сокета.

    В то же время, за те же деньги, что и Opteron 285, можно купить Xeon 5150 с той же тактовой частотой, но примерно в 1.5 раза быстрее. Материнские платы стоят почти одинаково, примерно в 1.5. раза дороже будет память, которая даст разницу около $500 на 8 гигабайт.

  • С другой стороны, складывается впечатление, что dual Xeon 51xx уже уперт в шину памяти, соответственно апгрейд на 4-ядерные версии в тот же сокет уже может иметь мало смысла, даже если приложения легко распараллеливаются.

Общие выводы

Помимо того, что Intel опять рулит, хочется отметить господина Kazushige Goto и его Goto BLAS, который не поленился написать довольно много мегабайт ассемблерного кода под все современные архитектуры. В наше время оптимизирующих компиляторов удивительно получать 10-кратное ускорение от ассемблера на довольно примитивных задачах.

И еще пара цифр. При перемножении матриц количество операций составляет 2*N3. Для матриц 8192x8192 это будет 1.1*1012 операций. Самый быстрый вариант умножателя, таким образом, дал скорость 48.6 Gflop/s для одинарной точности и 23.7 Gflop/s для двойной. Цифры, конечно, сугубо условные, к LINPACK-овским попугаям отношения не имеющие, но вообще это чуть больше 5 операций c плавающей точкой на такт (48.6/4 core/ 2.33 Ghz = 5.21). Теория гласит, что в архитектуре Core2 два блока с плавающей точкой, один из которых умеет делать только простые операции (4 за такт для single precision), а второй - всякие. Итого в пике, для multipy + add получаем 8 на такт когда все максимально оптимально. Таким образом, Intel выступил примерно на 2/3 от теоретически возможного пика.

У Opteron все проще - 4 операции (SP) на такт в теории. В практике: 30.8 Gflops/ 4 core /2.2 Ghz = 3.5 операции на такт или 88% от теории.

Comments

А почему память для Xeon в полтора раза дороже?

NB: Две опечатки у тебя: AMCL и "с плавающей точной".

Плюс баг в блоговом движке: оно нажатие preview считает за коммент, и если нажать через несколько секунд на post говорит, чтоб не спамил.

Опечатки поправил, баги поправил, спасибо.

А с памятью все просто:
DDR-400 регистровая стоит примерно $120 за гигабайтный модуль

FB-DIMM 667 стоит примерно 190 за гигабайтный модуль.

На 8 гигах набегает примерно 500.

"в 10 раз быстрее написанного руками кода на C" --- здесь было бы точнее сказать "написанного за две минуты кода на C".

За пару вечеров можно написать код, который будет не медленнее кода от вендора.

Достаточно посмотрет в сорец от Goto BLAS, чтобы понять что там не два вечера

Где указано какой алгоритм используется для перемножения матриц???
Насколько я знаю алг. Штрассена(Страссена) дает 2*N^2.8,
а это в 4 раза меньше операций чем для простого тройного цикла или блочного перемножения.

Почему "в 4 раза" ? Это зависит от N, правильно ?

Потом, там еще сложения. Которые, конечно, зависят от N^2, но там в среднем 3 на субматрицу,

Реально, все же упирается вовсе не в скорость умножатора, а в скорость памяти.

Как нас учили, смысл статей с описаниями опытов в возобновляемости результатов. Не хватает как минимум инфы на какой оси проводились испытания.

В-принципе, упрек понятный. Opteron - WinXP x64, Woodcrest - Linux (Gentoo какой-то)

Я подозревал, что там была Windows-машина. Однако автор GotoBLAS утверждает: "Currently Windows version doesn't support SMP". Действительно - ставим SMP=1, собираем - не собирается, ошибки явно своими силами не исправить. Получается опыты на 2х и 4х нитях нельзя было провести?

Прошел год и я боюсь сейчас наврать. Но - под оптеронами у нас много машин было/есть, если Goto не собирается под виндами, то значит тестировался под FreeBSD 6.x