Второй важнейший «культ», который определял развитие серверной архитектуры на протяжении десятилетий, – это «сакрализация» Linpack. Сам бенчмарк представлен Джеком Донгаррой аж в 1979 году. Но культовым статусом своим он обязан усилиям маркетологов из многих IT-компаний (Intel, AMD, IBM, Nvidia, Fujitsu и т. д.). Linpack имеет массу неоспоримых достоинств.
• Это всего лишь ОДИН тест, в отличие от, скажем, SPEC CPU, где их 40 с хвостиком.
• К тому же (в отличие от SPEC) он совершенно бесплатный.
• Очень легко объяснить, что Linpack делает. Он решает систему линейных алгебраических уравнений с числами двойной точности. Используется метод (P) LU-разложения (Гаусса) с выбором ведущего элемента.
• В качестве результата Linpack выдает ОДНО число – измеренную производительность системы в (гига-, тера-, пета-, экза-) флопах. На основании Linpack строится мировой рейтинг суперкомпьютеров TOP-500 и российский TOP-50. Так же вычисляют эффективность (искушенные люди обращают на нее внимание) – как отношение измеренной производительности к пиковой. Правда, в последнее время само понятие эффективности является несколько «размытым» из-за того, что в процессе исполнения теста тактовая частота может «плавать».
• Linpack идеально параллелится (MPI, OpenMP и вообще что угодно) и векторизуется.
• И, наконец, Linpack обеспечивает практически полную (> 90 %) загрузку вычислительных устройств. В то время как обычные приложения редко показывают больше 20.
И все же Linpack – это всего лишь ОДИН (и к тому же весьма специфичный) тест, и переоценка его роли обходится очень дорого. Тем не менее история показывает, что зачастую так оно и происходило.
Несмотря на интенсивный promotion со стороны маркетинга, Linpack не приобрел бы и половины своей популярности, если бы не вклад многих талантливых инженеров. Вслед за Донгаррой, безусловно, надо упомянуть Kazushige Goto. Этот парень – настоящий гений (вот только разговорный английский у него хромает), а его статья Anatomy of High-Performance Matrix Multiplication[5] давно стала «настольной книгой» для разработчиков библиотек. Я часто приходил к нему с разными вопросами по Линпаку: «Гото-сан, почему так?» И он обычно начинал свои объяснения фразой: «Ну вот представь, что ты – Linpack. Как бы ты поступил на его месте?» Конечно, я ничего не представлял. Просто сидел и слушал с открытым ртом. Потому что для меня это какой-то запредельный уровень понимания. Велик вклад ребят из интеловских MKL (а Linpack это на 95 % dgemm) и MPI. А также их аналогов для других платформ. Ну и не забуду коллег из Intel Competitive Response Team, в которой я провел восемь лет (2005–2013). В нашу задачу входила поддержка больших тендеров в области High Performance Computing[6], а также сопровождение подачи заявок в рейтинг Top-500 Supercomputers для свежепостроенных кластеров на базе процессоров Intel.
Top-500 – самый престижный мировой рейтинг суперкомпьютеров. Чтобы попасть туда, люди тратят десятки и сотни миллионов долларов. Нужно купить и собрать систему, которая может насчитывать десятки тысяч узлов и сотни тысяч интерконнектов. И когда все это сделано, остается последний (и очень ответственный) штрих – измерить производительность системы с помощью теста Linpack и подать заявку. Задача эта отнюдь нетривиальная – у нас была разработана многошаговая процедура для достижения максимального результата. Но надо понимать, что Linpack – это не только Computer Science[7], это еще и игра вероятностей. Продолжительность теста зависит от многих факторов: производительности процессоров, количества памяти на узел, количества MPI-ранков и OMP-тредов (если используется гибридная схема параллелизации) и т. д. Таким образом, время прогона может варьироваться от часа до десяти (а то и больше). А за это время с системой из нескольких тысяч узлов может случиться все что угодно – перегреться один из процессоров, отвалиться интерконнект, «cнести башню» драйверу и т. п. Поэтому мало все сделать правильно – нужно, чтобы тебе еще и немного повезло. И ты не можешь предсказать, когда это случится. Для того чтобы получить хороший результат, может потребоваться несколько сотен экспериментальных и «боевых» прогонов. Поэтому за 3–4 недели до International Supercomputing (июнь) и US Supercomputing (ноябрь) у нас начиналась горячая пора. Работа велась посменно и не прекращалась круглые сутки.
В тот день была моя очередь, и я появился на работе в 8:30. Экстремально рано по своим меркам. В офисе было пусто – график посещения в нашей развеселой лавочке был фривольный, и раньше 10–11 обычно никто не появлялся. Застал я только Серегу Шальнова, который гонял Linpack в ночную смену на немецком кластере.
– Чё как? – осведомился я за текущий статус.
– Ночной ран не выжил, – мрачно откликнулся Шальнов. – Сразу несколько узлов скопытились. Я полночи ковырялся, чтобы их вычислить и удалить из списка.
Потом мы наскоро прикинули «расклад» (параметры Np, P и Q) с учетом изменившегося количества узлов, и в этот момент у Сереги зазвонил телефон. Оказалось, что это Войтек, польский чувачок, который занимался технической поддержкой того кластера, на котором мы гоняли тест. Процесс его настолько захватил, что он приперся на работу даже раньше восьми по своему времени.
– Серега, заряжай! – прокричал Войтек так, что даже мне было слышно.
– Ты куда торопишься? – спросил Шальнов. – Скорее в историю войти?
– Дело не в этом. У нас тут похолодало. У меня в подсобке возле датацентра семь градусов. И если ты сейчас не запустишь Linpack (а тепла в процессе теста выделяется дай Бог), я тут сдохну от холода.
Серега положил трубу, посмотрел на меня уставшими, красными после бессонной ночи глазами и изрек:
– Предназначение Линпака не в том, чтобы быть мерилом человеческого тщеславия. Предназначение Линпака в том, чтобы приближать тепловую смерть Вселенной…
Если речь зашла о разных «мерилках», то уместно будет упомянуть о HPCC. Мой товарищ Андрей Нарайкин активно продвигал этот набор бенчей как «альтернативу» Линпаку. Нет, разумеется, HPL в составе High Performance Computing Challenge (HPCC) тоже был. Но кроме этого там присутствовали Stream (вечный «антипод» Линпака), Random Access и FFT (плюс несколько дополнительных). Я тогда стебался в том духе, что «Излюбленное занятие джентльменов – мериться размерами достоинства. А ты хочешь указать им на то, что у достоинства, помимо длины, есть еще и другие тактико-технические характеристики. Например, толщина, коэффициент расширения, угол стояния и т. п.» А теперь, спустя более 15 лет, я понимаю, насколько Андрюха был прав. Если бы джентльмены не зацикливались исключительно на длине достоинства, «Интел» сумел бы впоследствии избежать многих болезненных проблем.
Колоссальное (при этом не всегда положительное). Я не знаю другого бенчмарка, который оказал бы сравнимое воздействие на историю вычислительной техники в области HPC. Вторым, наверно, идет SPEC CPU, но разрыв огромен (по вышеперечисленным причинам). По сути, SSE2-SSE4, AVX, AVX2, AVX-512 – это все про Линпак. Я здесь остановлюсь на трех кейсах, которые протекали при моем (прямом или косвенном) участии.
• FMA впервые в истории Intel x86 увидел свет в процессоре Haswell. Fused Multiply-Add – это настолько же естественно, как улыбка младенца. Если ты занимаешься умножением, то сложение можешь получить практически бесплатно. Для целых чисел это очевидно, для чисел с плавающей точкой (IEEE754) чуть сложнее, но ненамного. К тому же, по счастливому стечению обстоятельств, наши алгоритмы (например, Dot Product) устроены так, что количество сложений и умножений примерно одинаково. И когда инициативная группа ребят предложила FMA под лозунгом «Линпак – в двойку!», c ними практически никто не спорил. Не, ну а чего спорить, когда ты получаешь сплошные плюсы без каких-либо серьезных минусов.
• AVX-512. Cледующая попытка удвоения производительности была связана с расширением длины SIMD. И вот тут, как говорится, «нашла коса на камень». Возражения возникли моментально, и сколько мы копий тогда сломали, в 2010-2013-х (примерно), пером не описать…
a. Нет в природе столь длинных векторов, чтобы эта машинка давала какие-то преимущества.
b. Tail processing[8]. Чем длиннее SIMD, тем большей проблемой становится обработка «хвостов» циклов, не кратных 8 (16, 32 и т. п.) операндам. Частично проблема решается маскированием, но лишь частично.
c. Mы в очередной раз уродуем кодировку команд, вводя расширение EVEX.
d. Bytes/Flop. Это было мое основное возражение. Мы усугубляем извечную проблему баланса между загрузками и числодробильными операциями (отношение stream/linpack). И эту архитектуру становится все тяжелее программировать.
e. Непонятно, насколько хорошо можно реализовать всю эту концепцию с физической точки зрения. Как ни странно, в тот момент «люди с паяльниками» вели себя на удивление тихо. Типа «надо – сделаем». И, как оказалось, напрасно…
И все же сила заклинания «Линпак – в двойку!» оказалась достаточной, чтобы перевесить все эти соображения. AVX-512 появился в Xeon Phi и Хeon (начиная со SkyLake) и сразу столкнулся со сложностями. Выяснилось, что основную роль играет именно последнее возражение. Функционирование AVX-512 приводит к перегреву кристалла, и непонятно, как с этим бороться. Упрощенно ситуацию можно описать так. При задействовании AVX-512 в единицу времени срабатывает очень много транзисторов. И они рассеивают много энергии в виде тепла. И ладно бы нагревание происходило равномерно по площади кристалла. С этим можно бороться – поставить кулер помощнее, подвести жидкостное охлаждение и т. п. Но беда в том, что перегрев происходит локально, и это делает проблему куда более злобной. Поначалу Intel пошел по пути наименьшего сопротивления – просто начал сбрасывать частоту при задействовании AVX-512 (в экстремальном случае чуть ли не на гигагерц). Это серьезно подсаживало производительность системы, но на тот момент представлялось временной мерой. Другой путь состоял в том, чтобы «размазать горячие вычисления» по площади кристалла (ядра). Однако тут возникла другая проблема – с синхронизацией и собиранием результата «в кучу». И она оказалась сложнее, чем представлялось изначально. За восемь лет усилий лучшие умы в области электроники так и не смогли подобраться к решению. То, что «Интел» постепенно отказывается от AVX-512, служит косвенным доказательством. И все же хочу сказать пару слов в защиту наших тогдашних решений. Это сейчас представляется «научно доказанным фактом», что 256 бит – оптимальная длина SIMD. А 10 лет назад это было ни разу не очевидно. Наступать на грабли – удел пионеров.
Xeon Phi явился, наверно апогеем культа Linpack. AVX-512 хотя бы умирает (и не факт, что умрет) мучительной смертью, следуя пожеланиям обычно нордически-сдержанного Линуса Торвальдса. В то время как Xeon Phi так и не сумел толком оторваться от взлетной полосы. Он задумывался как ответ набиравшим силу GPGPU. Концепция была такая: давайте натыкаем кучу слабосильных (в Knights Corner использовалась архитектура Pentium), низкочастотных ядер с «православной» ISA и снабдим их зубодробительной длины SIMD. Все это неплохо работало ровно на одном бенчмарке (угадайте, каком). Как только Xeon Phi сталкивался с критическими участками однопоточного кода (а такими, например, являются огромных размеров «cвитчи» в MPI), он немедленно шел на дно (кстати, ISA тут ни при чем.) Всего этого можно было бы избежать, если б в качестве основного теста был взят не HPL, а хотя бы HPCC. Но увы, случилось так, как случилось…
В момент краха Xeon Phi я был от этого уже довольно далеко. Последние годы в Intel (2016–2020) я провел, возглавляя команду VTune. И фокус моего внимания был сильно смещен в сторону uncore. Во-первых, хотелось какого-то разнообразия. Во-вторых, uncore-поляна, в отличие от core, была сильно менее изученной и «затоптанной». В-третьих, становилось понятно, что с увеличением числа ядер в процессоре роль core падает, а uncore – растет. Центром «анкорной» мысли тогда была тусовка под названием IO-intensive workloads group[9]. Я еще в шутку называл ее «клубом любителей DPDK». Кроме самого DPDK, в игре были и другие прилаги – базы данных, Hadoop, Ceph. Но всепроникающая сила Линпака в «Интеле» была такова, что он сумел меня достать и там. Проблемы наша группа обсуждала суровые. Вот есть core, uncore, шина и девайс – и все это работает на разных частотах. Как сопрячь, буферизовать и синхронизировать? А как быть с RDMA? В общем, почти любой доклад на этой группе так или иначе превращался в «плач Ярославны». И если core-тусовка, периодически наступая на грабли, оставалась более или менее на позитиве, то наша лавочка напоминала сборище неисправимых нытиков.
Был там такой «обряд посвящения», стихийно сложившийся и оттого особенно смешной. Бывало, приходил к нам мальчик, только что закончивший Стенфорд, Беркли или другое уважаемое учебное заведение Объединённых Штатов Северной Америки. Первый раз он обычно сидел тихо, внимательно слушая наши стенания. Зато в следующий раз приходил одухотворенный.
– Ребята, я понял, что надо сделать.
– Ну и?
– Надо понизить частоту ядра. Ведь оно все равно по большей части ждет ввода-вывода. И чем меньше оно намолотит тактов в этом процессе, тем лучше, – в этот момент у ветеранов тусовки делались уксусно-кислые лица. Типа «ну вот, еще один юный гений»…
– Все это логично, правильно и было бы хорошо, если б не одно «но», – в тот день была моя очередь «резать правду-матку».
– Какое?
– Знаешь, что сделает с нами маркетинг за недобор флопов на Линпаке? Он утопит нас в пруду. Всех в одном мешке, как котят. Даже не будет разбираться, чья идея была.
– Правда? – голос у паренька заметно дрожал.
– Ага. Добро пожаловать в реальный мир.
На этом разговор закончился, но спустя некоторое время пожилой и уважаемый всеми индус, который председательствовал в группе, сделал мне замечание в личной беседе:
– Зря ты так, Валер. Парнишка прям серьезно расстроился.
– Да ладно, пусть привыкает. Здесь не Стенфорд.
И тут он меня ненавязчиво осадил:
– Ну, ты сам-то вспомни, что сказал, когда первый раз к нам пришел…