Современные технологии автоматического распараллеливания позволяют поднимать производительность работы последовательных кодов, и теперь иногда трудно понять — быстрее ли работают появившиеся на рынке процессорные ядра или высокое быстродействие было достигнуто за счет увеличения их числа. В этом смысле, после разрешения применять в тестах автоматическое распараллеливание компиляторами, тесты SPECcpu2006 (табл. 1) перестали быть точной метрикой производительности процессоров при выполнении последовательных программ, с которыми сегодня работает подавляющее большинство пользователей. При этом стало труднее сравнить даже производительность процессоров, поскольку однопроцессорные результаты для серверов уже приводятся не всегда. Например, в случае с Intel Xeon E3 на базе Sandy Bridge сегодня возможны только однопроцессорные версии, а для их конкурентов обычно приводятся лучшие данные для двух и более процессорных систем.
Таблица 1. Производительность м микропроцессоров |
Для 16-ядерных процессоров Opteron 6200 с микроархитектурой Bulldozer, поддерживающей расширение AVX (Advanced Vector Extensions), официальные данные по SPECint2006/SPECfp2006 вообще отсутствуют, представлены лишь данные по SPECint_rate2006/SPECfp_rate2006. По первому показателю один процессор Xeon Е3-1280 опережает два процессора Opteron 6204 (cамая высокочастотная модель с четырьмя ядрами — 3,3 ГГц, в турборежиме — 4,2 ГГц). По показателю SPECfp_rate2006 компьютер с двумя Opteron 6204 и с вдвое большим числом ядер быстрее однопроцессорного E3-1280 в 1,3 раза. Учитывая, что данные rate-тестов почти линейно масштабируются с числом процессоров, можно предположить, что ядра Bulldozer сегодня отстают по производительности от доступных Xeon E3. Имеется отрыв по производительности одиночных ядер и процессоров Xeon E3 относительно Opteron предыдущего поколения. По базовому значению SPECfp2006, как и по SPECint2006, Xeon сильно впереди относительно Power7. Лишь на SPECfp2006 процессоры Power7/3,86 ГГц опережают по пиковому значению E3-1280.
Возможно, на результаты SPECfp_peak2006 сказалось и автораспараллеливание у IBM на 16 ядрах (два процессора) против четырех ядер (один процессор) у Intel. Кроме того, результаты Intel могут быть выше на E3-1290 c более высокой, чем у 1280, тактовой частотой (3,6–4 ГГц при использовании Turbo Boost), не говоря уже об ожидаемых многопроцессорных вариантах Xeon/Sandy Bridge. Но если брать пиковую производительность с плавающей запятой, то Power7 окажется впереди — его максимальная тактовая частота, 4,14 ГГц, чуть выше, чем у E3-1290 (4 ГГц): оба процессора способны выдавать восемь результатов двойной точности за такт. Важно учитывать также отношения стоимость/производительность и, особенно для HPC-приложений, «плотность упаковки», связанную с числом ядер в процессорах (она очень высока в Opteron 6200), а также тепловыделение.
Микроархитектура
Приведенный здесь анализ представляет интерес не только для ознакомления с аппаратными средствами, но и для программистов, в первую очередь на ассемблере. Микроархитектура ядра Sandy Bridge (см. рисунок) была значительно усовершенствована по сравнению с Nehalem [ 1 ], причем наиболее существенным улучшением стало увеличение числа исполнительных устройств (EU) c плавающей запятой. Это привело к тому, что за каждый такт выдается вдвое больше результатов с плавающей запятой (с двойной точностью — восемь). Важным также является поддержка 256-разрядного расширения AVX.
Общая блок-схема конвейера Sandy Bridge |
Во фронтальной части конвейера (обозначим ее как FE) последовательно выбираются команды и декодируются в микрооперации (MOP), обеспечивая их потоком последующие стадии обработки. Соответствующие им блоки микропроцессоров все вместе иногда именуют «исполнительным движком» (Execution Engine, EE). В Sandy Bridge — это суперскалярный (до шести МОР за такт) блок, обеспечивающий внеочередное выполнение МОР. Движок фактически реализует архитектуру потока данных (dataflow) — МОР начинают выполняться, как только становятся готовы исходные операнды и исполнительные ресурсы.
Последние стадии конвейера (после выполнения МОР) реализуются с применением устройства «завершения» (RU, retirement unit), в котором осуществляется обработка исключительных ситуаций выполнения, а результаты делаются «видимыми» в порядке, определяемом исходным кодом программы.
Фронтальная часть конвейера содержит буферы быстрой переадресации TLB и двухуровневую кэш-память ядер — кэш старшего уровня (L3) разделяется всеми ядрами процессора и подсоединен к кольцевому межсоединению. Кэш-память команд и данных (I и D) L1 имеют емкость по 32 Кбайт и являются 8-канальными наборно-ассоциативными (в Nehalem I-кэш был четырехканальным). Кэш L2 емкостью 256 Кбайт разделяется командами и данными. Длина строки в кэшах всех уровней равна 64 байт, во всех кэшах реализована обратная запись. Когерентность кэшей поддерживается с помощью протоколa MESI (Modified, Exclusive, Owner, Invalid). Пропускная способность у всех кэшей составляет 32 байт за такт.
Проведенные в Sandy Bridge усовершенствования в иерархии TLB повышают производительность, в первую очередь для приложений с большим рабочим множеством страниц. I-TLB в Sandy Bridge имеет емкость 128 строк для страниц емкостью 4 Кбайт (как в Nehalem) и восемь строк (против семи в Nehalem) для страниц по 2/4 Мбайт. Емкость D-TLB для страниц размером 4 Кбайт и 2/4 Мбайт составляет 64 и 32 cоответственно; кроме того, D-TLB поддерживает теперь страницы по 1 Гбайт (четыре строки). Буфер D-TLB обеспечивает три преобразования линейного адреса в физический за такт (два для адресов загрузки и одно для адресов записи), что отвечает возможностям одновременного выполнения Sandy Bridge трех соответствующих команд. При промахе в I-TLB или D-TLB обращение идет в общий для команд и данных TLB второго уровня, STLB, емкостью 512 строк для страниц в 4 Кбайт. При промахе в I-TLB/D-TLB и попадании в STLB задержка равна семи тактам.
В FE устройство предсказания переходов (назовем его BPU) указывает на блок кодов программы, который выбирается из кэша декодированных команд (Decoded I-cache, DI-кэш), из I-кэша, из кэшей L2, L3 или из оперативной памяти. При выборке из I-кэша используются традиционные для Intel четыре декодера СISC-команд в МОР, первый из которых декодирует команды, порождающие до четырех МОР, а оставшиеся — по одной МОР. Более сложные CISC-команды используют последовательности МОР, хранящиеся в ROM-кэше.
Декодеры направляют MOP в очередь (MOP туда могут попадать и прямо из DI-кэша) и в DI-кэш. В очереди реализован также детектор циклов (Loop Stream Detector), распознающий циклы длиной не более 28 МОР, целиком размещающиеся в очереди. При обнаружении такого цикла его тело «закрепляется» в очереди МОР. Однако раскрутка (unrolling) циклов обычно более предпочтительна для повышения производительности.
Все декодеры поддерживают микро- и макро-«объединение» (fusion). При микрообъединении несколько МОР одной команды объединяются в одну сложную МОР, что типично для операций работы с памятью. При макрообъединении две команды сливаются в одну МОР. Первая команда из пары устанавливает флаги (например, сравнение), а вторая — условный переход. Микро- и макрообъединение увеличивает, в частности, пропускную способность конвейера.
Применение DI-кэша более эффективно по сравнению с применением обычных стадий декодирования. Благодаря DI-кэшу растет скорость доставки МОР к исполнительным блокам и уменьшается задержка при неправильном предсказании перехода. Емкость DI-кэша составляет 1536 МОР.
EE реализует финальные стадии конвейера и включает устройства переименования регистров/распределения ресурсов, устройство завершения (RU) и планировщик с исполнительными устройствами (EU). Блок EE, по сравнению с Nehalem, был усовершенствован для повышения среднего числа выполняемых за такт команд. Так, с 36 до 54 возросло число строк в планировщике, выросло также число буферов для операций загрузки регистров/записи и др.
Блок переименования регистров убирает ложные взаимозависимости между МОР, обеспечивая возможности их внеочередного выполнения. Этот блок за такт выбирает до четырех МОР (включая объединенные) из очереди МОР. Исходные архитектурные регистры и регистры результата здесь переименовываются во внутренние микроархитектурные, распределяются ресурсы (например, буферы загрузки/записи), определяются нужные порты диспетчеризации МОР. Здесь же выполняются некоторые примитивные команды типа «нет операции», разные формы обнуления регистров и др. В этом блоке может распределяться до двух команд перехода за такт (против одной в Nehalem). Это, конечно, способствует росту производительности.
В EE в Sandy Bridge был внесен ряд доработок, приводящих к уменьшению вероятности простоя (stall), уменьшению числа конфликтов и задержек обратной записи и др. EE включает три исполнительных стека: целочисленный общего назначения; для векторных (single instruction, multiple data, SIMD) команд, как целочисленных, так и с плавающей запятой; для команд набора x87.
Планировщик направляет МОР в один из шести портов выдачи, и эти МОР выполняются в соответствующих EU. На стадии завершения результаты выполнения выбираются в соответствии с указанным в исходном коде порядком.
Трудно перечислить все нововведения Sandy Bridge, но стоит еще упомянуть поддержку двух важных для повышения производительности технологий: HyperThreading, позволяющей получить два логических процессора вместо каждого физического ядра, и TurboBoost, позволяющей автоматически повышать частоту ядер относительно номинальной, если это разрешают термические условия.
Межсоединение процессорных ядер в Sandy Bridge представляет собой двунаправленную кольцевую шину. К ней подсоединены системный агент, кэш L3 и интегрированное графическое устройство (в некоторых моделях процессора E3 оно может отсутствовать). Пропускная способность шины при тактовой частоте ядер в 3 ГГц равна 384 Гбайт/с. Кэш L3 имеет четыре «среза» — по числу ядер в процессоре; каждый срез включает собственный порт, способный передавать 32 байт за такт.
Системный агент содержит в себе арбитр доступа к кольцу, контроллер дисплея, контроллеры PCIe (x16+x4/2*x8 +x4/x8 +3*x4), контроллер шины DMI, через который подсоединяется южный мост, и контроллер памяти. Последний поддерживает два канала DDR3/1066, 1333 или 1600 шириной 8 байт каждый. Каждый канал осуществляет внеочередную обработку запросов, реализуемую собственным планировщиком, и буфер данных емкостью 32 строки кэша. B Xeon с микроархитектурой Nehalem каналов памяти было три; возможно, в поддерживающих мультипроцессирование Xeon/Sandy Bridge каналов также будет три.
Четырехъядерные Xeon E3 производятся по технологии 32 нм, содержат около 1 млрд транзисторов и имеют тепловыделение до 95 Вт (у старших моделей).
Расширение AVX
Главным новшеством в Sandy Bridge, возможно, следует признать архитектурное расширение системы команд AVX [ 2 ]. AVX вводит 256-разрядные векторы и SIMD-регистры cоответствующей длины; новый трехоперандный синтаксис с новым префиксом VEX (вероятно, от Vector Extensions) для кодирования команд и расширения FMA (fused multiply-add, то есть команды типа «умножить-и-сложить», «умножить-и-вычесть» и др.) повышенной точности в соответствии со стандартом IEEE754/2008.
256-разрядные регистры YMM0-YMM15 в своих нижних 128 разрядах «эквивалентны» регистрам XMM. Вместе с VEX вводится также большое число новых команд с функциональностью, совпадающей с имеющимися ранее, но кодируемых с помощью VEX. Кроме того, в AVX представлены новые команды с новой функциональностью: загрузки 256-разрядных векторных регистров и пересылки между ними, команды работы с отдельными битами, расширенная команда умножения MULX для «длинных» целых чисел и др.
Поддержки 256-разрядной FMA в Sandy Bridge пока нет, вероятно, она появится в следующем поколении Ivy Bridge с типоразмером 22 нм. Там же ожидается поддержка расширения AVX2, которое включает работу с 256-разрядными целочисленными данными. Одновременно с поддержкой FMA возрастет и количество получаемых за такт результатов с плавающей запятой.
Измерения производительности
Для приведенных тестов использовался однопроцессорный сервер на базе Xeon E3-1240 3,3 ГГц (тактовая частота была фиксирована, поэтому пиковая производительность с двойной точностью была равна 26,4 GFLOPS) с памятью DDR3 8 Гбайт с симметричным заселением обоих каналов памяти. Некоторые результаты были сопоставлены с [ 3 ] для двухпроцессорного сервера с четырехъядерными Xeon E5520 2,27 ГГц (c микроархитектурой Nehalem) и памятью DDR2-1066 емкостью 12 Гбайт, расселенной равномерно по шести каналам памяти. Измерения проводились в 64-разрядной среде OpenSuSE 11.4 с использованием, в частности, Intel Fortran XE Composer 2011 версии 12.1/6.233 и библиотеки математических программ MKL 10.3.
Тесты Linpack при размерности задачи n=100 (табл. 2) являются хорошей оценкой производительности с плавающей запятой — влияние памяти здесь отсутствует, поскольку задача хорошо локализуется в кэше. Для ключей компиляции -fast и -xAVX достигается производительность 4,7 GFLOPS, но если ограничиться применением кодов SSE4.2 (-xSSE4.2), то производительность будет 5,0 GFLOPS. Не всегда применение команд AVX дает более высокую производительность.
Таблица 2. Производительность сервера на базе Xeon E3-1240 на некоторых последовательных тестах |
Интересно сравнить эти данные с результатами для Nehalem (2,6 GFLOPS), пересчитав производительность на единицу тактовой частоты, — окажется, что производительность ядра Sandy Bridge по сравнению с Nehalem выросла на 36%.
Данные тестов Linpack при n=1000 представляют аналогичный интерес, но здесь результаты определяются производительностью работы оптимизированных модулей (dgetrf, dgetrs) библиотеки MKL. На одном ядре при этом достигается производительность 18,9 GFLOPS, сопоставимая с пиковой, а в расчете на единицу тактовой частоты по сравнению с Nehalem производительность возросла на 71%. Это неплохое доказательство эффективности расширения числа устройств с плавающей запятой в Sandy Bridge. Распараллеливание теста на два и четыре ядра (табл. 2) следует признать вполне удовлетворительным.
Производительность ядра E3-1240 при умножении больших матриц (с применением MKL-модуля dgemm, n=8000) в расчете на единицу тактовой частоты возросла почти вдвое и составляет 24,7 GFLOPS — около 94% от пикового значения.
Результаты стандартных для оценки пропускной способности памяти тестов stream особенно важны для чувствительных к этому показателю приложений (например, вычислительной гидродинамики). Для многоядерных процессоров всегда встает проблема распределения пропускной способности между ядрами, которые могут вступать в конфликт по доступу в память — эта ситуация была обнаружена и в E3-1240.
Компиляция с ключами -fast -openmp (-xSSE4.2 слабо влияет на результат по сравнению с -xAVX) уже и на одном ядре позволяет достигнуть пропускной способности до 17,7 Гбайт/с (табл. 3), что достаточно близко к пиковому значению — 21,3 Гбайт/с для двух каналов DDR3-1333. На двух ядрах пропускная способность возрастает до 18,8 Гбайт/с, а на четырех уже уменьшается. Если компилятор не может так оптимизировать, как компилятор Intel (например, gfortran версий до 4.6.0 без поддержки Sandy Bridge), то масштабирование с числом ядер может быть выше.
Таблица 3. Производительность с распараллеливанием |
Таблица 4. Ускорение при расчетах по Gaussian-09 |
В качестве иллюстрации распараллеливания реальных приложений приведены данные по задачам молекулярного моделирования (табл. 4) в квантовой химии, в рамках пакета Gaussian-09 [ 4 ]. В расчетах использованы молекулы тринитротриаминобензола (из стандартного test178, методом CIS), валиномицина (test397, DFT) и фуллерена C60 (DFT c расчетом частот), все — без учета симметрии.
Данные табл. 4 говорят о хорошем распараллеливании всех этих задач. Для фуллерена даже без перетрансляции кодов Gaussian-09 (под E3) при выполнении на Sandy Bridge производительность ядра E3-1240 в расчете на единицу тактовой частоты выше, чем у Nehalem.
Литература
- “Intel 64 and IA-32 Architectures Optimization Reference Manual”, 248966-025, Intel, June 2011.
- “Intel Advanced Vector Extensions Programming Reference”, 319433-011, Intel, June 2011.
- Михаил Кузьминский, Nehalem: микроархитектура и производительность , Открытые системы. СУБД, № 8, 2009.
- Gaussian 09, Revision A.02, M. J. Frisch e.a., Gaussian, Inc., Wallingford CT, 2009.
Михаил Кузьминский (kus@free.net) — старший научный сотрудник Института органической химии им. Н. Д. Зелинского РАН (Москва). Работа поддержана РФФИ, проект 11-07-00470.