![](https://habrastorage.org/getpro/habr/upload_files/31b/0d7/b0c/31b0d7b0cb6d64327069bdd85cb12abf.jpg)
После полученных на предыдущие статьи о микропроцессоре Эльбрус откликов мне стало понятно, что для полноты картины не хватает рассмотрения вопроса – а что же делать? Можно ли каким-либо образом улучшить Эльбрус в качестве general-purpose CPU (на что намекали представители МЦСТ) и насколько? Можно ли его применить в каких-то локальных нишах? Давайте попытаемся разобрать данные вопросы.
Доработка микропроцессора Эльбрус для улучшения его характеристик в качестве general-purpose CPU
Как я упоминал в предыдущих статьях, проблемы VLIW-архитектур и статического планирования операций давно известны в индустрии. Поэтому в нашем анализе мы можем опираться не только на некоторые абстрактные идеи и соображения относительно архитектуры Эльбрус, но и на опыт разработки других VLIW-процессоров линеек Intel Itanium, Transmeta, Nvidia Denver, который зачастую очень показателен.
Итак, какие улучшения возможны в Эльбрусе, чтобы улучшить его характеристики в качестве GP CPU процессора?
Локальные микроархитектурные улучшения
Мы опустим мелкие изменения, которые фундаментально ни на что не повлияют. Но есть две вещи, которые жизненно необходимы для микроархитектуры Эльбрус – аппаратный префетчер данных (hardware prefetcher) и предсказатель ветвлений (branch predictor). Данные улучшения не дадут прироста на цифрах Spec CPU2006/2017, которые Алексей Маркин представил в своей статье, т.к. эти результаты получены на пиковых опциях с профилем (а значит, там сделан софтварный префетч и нет проблем с неудачными вызовами в горячих циклах). Но зато они существенно помогут при запуске «неоптимизированного» кода, как в примере с вызовом функции из первой статьи. Это не решит множества других проблем, но даст определённый прирост микроархитектурной скорости на реальных задачах.
Правда, здесь есть один важный нюанс: алгоритмы современных префетчеров и предсказателей достаточно нетривиальны, а в топовых процессорах они вылизывались десятилетиями. Поэтому сразу сделать хорошую реализацию этих модулей не получится - доведение до хороших характеристик потребует немало времени. В первых же версиях новые функциональности будут сбоить и иногда давать заметные ухудшения.
Также возникает проблема совместимости с кодом, откомпилированным под более ранние версии Эльбруса. И если добавление аппаратного префетчера можно сделать прозрачно, то внедрение предсказателя переходов в зависимости от реализации, либо вообще приведёт к несовместимости со старым кодом, либо не даст на старом коде никакого улучшения (вернее, даже даст ухудшение). Т.е. так или иначе, для получения преимуществ новых микроархитектурных улучшений потребуется перекомпиляция всей программной экосистемы.
Спикеры от МЦСТ заявляли, что предсказатель ветвлений планируется к реализации в новых версиях Эльбруса, а аппаратный префетчер чуть ли не уже реализован (правда, никакого упоминания об этом в публичных спецификациях я не нашёл).
Ну и не могу не отметить, что озвученные улучшения – это первый шаг к отходу от концепции статического планирования, сделанного «умным» компилятором.
Что касается других VLIW-процессоров общего назначения, то линейка Intel Itanium изначально имела branch predictor, а в процессе развития получила и hardware prefetcher. Что касается процессоров от Transmeta и Nvidia, то про их архитектуры намного меньше информации (они были скрыты под системами двоичной трансляции), точные данные мне неизвестны, но вероятнее всего, предсказатели ветвлений они в каком-то виде имели.
Динамические оптимизации
Собственно говоря, если обобщить мерцающие технические контраргументы в пользу микроархитектуры Эльбрус в различных дискуссиях, то они сводятся как раз к реализации «динамических оптимизаций». Примерно так это звучит со стороны неофициального телеграм-канала МЦСТ:
В МЦСТ работал сотрудник с такими же именем и фамилией, занимался двоичной трансляцией. Если это не совпадение, а детали и язык говорят, что это он, то Максим действительно знает архитектуру изнутри. Но против его аргументов есть контр-аргументы. Главный - что здесь рассмотрен случай компиляции помодульной, без использования какого-то профиля. А в нормальной "промышленной" реализации не хватает чисто софтварного инструмента - получения профиля от реального использования ПО и докомпиляция этого ПО с учётом профиля и всех имеющихся динамических библиотек.
Это не совсем тривиально, но именно с таким инструментом большинство аргументов Максима "против" можно снять.
И сама архитектура Эльбрус не стоит на месте, в неё добавляются динамические механизмы (уже добавлен префетчер, добавляются в следующей реализации предсказатели переходов и т.п.)
А так в статье Алексея Маркина (автора статьи в защиту Эльбруса):
Для качественной компиляции необходимо понимать, какие участки кода исполнялись больше, а какие меньше. Для этого существует понятие профилирующей компиляции. Это двупроходная сборка, на первом проходе которой выполняется сборка с опцией -fprofilegenerate, после чего программа запускается на обучающем наборе данных. Во время этого обучающего запуска программа выполняет сбор информации о переходах по ветвлениям, вызовах функций и исполнении циклов. На втором проходе производится сборка с опцией - fprofile-use, во время которой компилятор использует полученную информацию для определения оптимального набора и области применения оптимизаций. Использование этой технологии позволяет ускорить исполнение программ в среднем более чем на 17%. Такая схема бывает сложна для пользователя, более того она требует подбора тестовых данных таким образом чтобы программа исполнялась на тех же маршрутах что и при пользовательских данных
…
К перспективным исследованиям можно отнести использование возможностей аппаратного профилирования процессоров Эльбрус-16С для динамической оптимизации исполняемого кода
Показательно, что представители МЦСТ здесь явно признают наличие проблем производительности при компиляции без профиля, и даже совершенно верно указывают, что сбор профиля – это «не совсем тривиально».
Так что же означают эти туманные «динамические оптимизации»? На самом деле, всё достаточно банально – фактически речь идёт о реализации динамического оптимизатора наподобие JVM, который будет работать во время исполнения программы, в динамическом режиме собирая профиль и делая оптимизации, на нём основанные. А аппаратная поддержка тут нужна для сбора качественного профиля с минимальными накладными расходами.
Чисто в теории это - правильное направление. Например, VLIW-процессоры от компании Transmeta и линейка Nvidia Denver изначально исповедовали именно такой подход – они всегда работали ТОЛЬКО в режиме динамической трансляции. Таким образом они решали и проблему программной совместимости (эмулируя архитектуру x86 в случае Transmeta и ARM в случае Nvidia), и проблему отсутствия профиля. Потому что заставить всю программную экосистему переехать на компиляцию с профилем просто нереально, и в компании МЦСТ это тоже прекрасно понимают.
Но у этого решения есть вполне очевидная цена – необходимо разработать эффективный динамический оптимизатор, доработать программную экосистему, всё это интегрировать вместе, и к тому же опять перекомпилировать коды (потому что наиболее эффективная схема реализации динамических оптимизаций требует доработок компилятора lcc). Создать такое решение продуктового уровня даже при наличии опытной команды и достаточных ресурсов – это много лет разработки (я бы оценил в 5-10 лет), а в условиях кадрового голода МЦСТ у меня сомнения в реализуемости такого проекта в принципе. Недаром на текущий момент самые плохие цифры производительности у Эльбруса как раз на бенчмарках различных языков с динамической трансляцией байткода (Java, Javascript и т.д.). И опять-таки, это всё приводит к усложнению программного стэка (например, придётся отлаживать ошибки в коде, созданном динамически «на лету»), а как следствие - к увеличению количества сложных багов и проблем с интеграцией всего этого хозяйства.
Как «динамические оптимизации» улучшат ситуацию, даже если всё вышеописанное в конце концов сделать? Для цифр Spec CPU2006/2017 это снова не даст никакого роста производительности – напомню, что заявленные результаты от МЦСТ получены на пиковых уровнях оптимизации с профилем. Улучшения будут присутствовать опять-таки на «неоптимизированном коде» и составлять они будут в среднем порядка 17% - если ориентироваться на цифры, представленные Алексеем в своей статье (и эти цифры примерно согласуются с моими оценками).
Радикальная переработка микроархитектуры
Самый перспективный, но, к сожалению, нереалистичный вариант. Нереалистичный потому, что масштаб переделок таков, что он сопоставим с разработкой абсолютного нового процессора с нуля. При этом направление изменений будет диктовать отказ от множества особенностей Эльбруса, что по факту полностью девальвирует саму идею VLIW и статического планирования.
Но давайте подробнее. Для желающих глубже погрузиться в вопрос сложностей VLIW-архитектур, как их пытались решить и почему в итоге это направление было признано бесперспективным для general-purpose CPU, я настоятельно рекомендую поизучать историю линейки процессоров Intel Itanium. Как по мне, она крайне показательна. Ведь в разработку Intel Itanium были вложены огромные усилия и ресурсы – компания Intel видела в данной линейке свою будущую 64-битную архитектуру, из-за чего даже упустила создание x86-64 со стороны AMD, и была вынуждена догонять конкурента.
Особый интерес в плане изучения опыта Intel Itanium для нас представляет статья с говорящим названием «General Purpose VLIW is Dead»(ссылка). В ней описана микроархитектура уже 7-го поколения процессоров Itanium с кодовым именем Poulson. Это - вершина развития линейки Intel Itanium в плане микроархитектуры. Последнее, 8-ое поколение Kittson было де-факто тем же Poulson с улучшенными частотами. Посмотрим на схему микроархитектуры Poulson в сравнении с предшественником Tukwila:
![](https://habrastorage.org/getpro/habr/upload_files/6ef/6f3/c53/6ef6f3c53974c12e133af242c288cf6b.png)
Для Tukwilla всё типично для VLIW-архитектуры – инструкции, поступая с декодера, читают значения из регистрового файла и отправляются дальше на исполнительные устройства (последние на картинке опущены).
А что мы видим для Poulson? Инструкции с декодера попадают в Instruction buffer, а дальше - Branch Queue, ALU Queue, Memory Queue и т.д. Хм, да это же попытка реализовать простейший ОоО в условиях VLIW! По этому поводу автор статьи пишет:
Tukwila and all earlier Itanium designs were VLIW microarchitectures; compiled bundles formed the basis of execution and instructions were statically scheduled. Any dependencies were resolved by global stalls. The global stall microarchitecture would halt the entire pipeline until the problem had been resolved.
Poulson is fundamentally different and much more akin to traditional RISC or CISC microprocessors. Instructions, rather than explicitly parallel bundles, are dynamically scheduled and executed. Dependencies are resolved by flushing bad results and replaying instructions; no more global stalls. There is even a minimal degree of out-of-order execution – a profound repudiation of some of the underlying assumptions behind Itanium
Последнее предложение подводит знаковую черту под концепцией VLIW-архитектур – в итоге своего развития они пришли к тому, что необходимо реализовывать ОоО-исполнение внутри процессора. А в таком случае все особенности VLIW – это лишь помеха. Поэтому отказ от VLIW-архитектур для general-purpose CPU стал неизбежностью.
В условиях Эльбруса всё аналогично. Если делать столь радикальные переделки микроархитектуры с реализацией ОоО во VLIW-архитектуре, то это колоссальная по сложности работа. Причём по её итогу придётся просто выбросить многие «фишки» Эльбруса, которые станут ненужными. А главное – сама концепция широкой команды в таком случае становится не только бессмысленной, но даже вредной. Поэтому намного проще взять обычную RISC архитектуру и сделать на её основе современный процессор с ОоО-исполнением. Это будет проще, быстрее, дешевле, а в итоге получится более быстрый и удобный для пользователей процессор.
Давайте подведём небольшой итог. Из реалистичного (префетчер, предсказатель ветвлений,и даже пусть динамические оптимизации) - в Эльбрусе можно сделать набор определённых улучшений, которые позволят улучшить производительность на реальных задачах. При этом из предыдущих статей помним, что верхний предел микроархитектурной скорости на Эльбрусе, рассчитанный по данным запусков на Spec CPU2017, в 3-4 раза уступает современным RISC/CISC процессорам с ОоО исполнением. Эта оценка не изменится. Для «неоптимизированного кода», где производительность может деградировать в разы от микроархитектурной скорости на Spec CPU2017, ситуация улучшится. Ввиду отсутствия Эльбрусов в свободном доступе нет возможности привести точные значение ускорения. Но, я бы грубо оценил, что на коде из реальной жизни средняя производительность сейчас падает в 2 раза по сравнению с цифрами на Spec CPU2017, т.е. Эльбрус по микроархитектурной скорости приблизительно в 6-8 раз хуже современных RISC/CISC аналогов. Предложенные улучшения подтянут это соотношение где-то к 5.
Из вышеизложенного, как мне кажется, вывод достаточно очевиден – попытка допилить Эльбрус принципиально ничего не изменит. Как general-purpose CPU он всё равно будет существенно уступать современным RISC/CISC аналогам именно в силу изначальной концепции, заложенной в архитектуру. Индустрия этот путь прошла, различные варианты решения проблемы известны и изучены, они не помогают. Яркий пример в этом отношении - история линейки Intel Itanium. Компания МЦСТ в данный момент лишь пытается повторить то, что 20 лет назад уже было опробовано. Но результат здесь уже известен заранее.
Потенциальные ниши для применения микропроцессора Эльбрус
Но бесперспективность Эльбруса как general-purpose CPU ещё не говорит о том, что не существует локальных ниш, в которых он может быть конкурентоспособен. Попробуем проанализировать, где микропроцессор Эльбрус всё же может найти своё применение.
Специализированные процессоры
Хотя VLIW-архитектуры больше не применяются в general-purpose CPU, тем не менее, они находят широкое применение в специализированных решениях, таких как DSP процессоры и графические процессоры (хотя в графике VLIW-архитектура тоже уже не самый оптимальный подход). Но переделывать Эльбрус в решения такого рода малоэффективно. Данный процессор изначально проектировался для серверного и десктопного сегментов, в нём множество вещей, не нужных для специализированных решений, и наоборот – нет необходимой специфики для других доменов. Можно на базе наработок Эльбруса создать какое-то решение, но это де-факто будет разработка нового специализированного чипа. Поэтому данное направление развития не является сколь-либо перспективным для Эльбруса, на мой взгляд.
Решения для безопасности
В Эльбрусе есть две функциональности связанные с безопасностью, отсутствующие в массовых процессорах, доступных сейчас на широком рынке – это отдельный стек вызовов и аппаратная поддержка тегированной памяти. В остальном он ничем принципиально не отличается по безопасности от современных RISC/CISC процессоров.
Отдельный стек вызовов – полезная «фишка», но проблема в том, что она закрывает только одну из множества потенциальных угроз – так называемую ROP-атаку. При прочих равных, это приятное дополнение, но только при условии, что по остальным характеристикам процессор конкурентоспособен. Т.к. для Эльбруса это не так, то ценность наличия отдельного стека вызовов становится нулевой.
А вот с тегированной памятью, на мой взгляд, ситуация интереснее. В теории, компиляция и запуск программы в таком режиме (называемым защищённым) позволяет обнаруживать различные ошибки и потенциальные уязвимости в коде. Сейчас в индустрии многие крупные компании тратят серьёзные ресурсы на поиск и исправление ошибок в своих продуктах, используя разные программные средства статического и динамического анализа корректности поведения программы. Вполне возможно, что для них будет интересно использовать программно-аппаратное решение на базе Эльбруса, если оно будет быстрее или качественнее. Правда, данный рынок крайне мал, и вряд ли там потребуется больше нескольких тысяч Эльбрусов. Но это уже задача для маркетологов МЦСТ - детальнее разобраться в потенциале данного направления
Запуск Windows-приложений
В контексте импортозамещения может возникнуть ситуация, когда некоторый софт будет возможно запустить только под Windows. И если сделать эффективное решение по двоичной трансляции для Linux-приложений можно без аппаратной поддержки, то запустить Windows без помощи со стороны процессора уже достаточно сложно и требует большого времени на разработку. В то же время в Эльбрусе аппаратная поддержка для двоичной трансляции и сам транслятор уже присутствуют. В том случае, если пользователи готовы смириться с существенной потерей в производительности, решение на базе Эльбруса вполне может им подойти. Но тут есть одна стратегическая проблема – если мы ставим процессоры в рамках импортозамещения, то странно для таких решений использовать ОС Windows. Т.е. переход на Linux-based дистрибутивы и перевод всего программного обеспечения под Linux в данном случае будет лишь вопросом времени. Поэтому Эльбрус здесь может выступать лишь как решение для переходного периода, и в перспективе этот рынок будет стремиться к нулю.
High Performance Computing (HPC)
Если мы внимательно посмотрим на характеристики процессора Эльбрус, то заметим, что он обладает достаточно внушительными показателями так называемых GFLOPS. Иными словами, потенциально, Эльбрус может совершать очень большое количество операций над вещественными данными за единицу времени. Например, для самого последнего процессора от МЦСТ Эльбрус – 16С этот параметр составляет 750 GFLOPS для вещественных чисел двойной точности. Этот показатель не просто внушителен в пересчёте на одно ядро, где он вплотную подбирается к самым топовым решениям от Intel, но даже очень прилично выглядит в абсолютных значениях. Самый производительный процессор от Intel, который я нашёл в данном списке, имеет 1612 GFLOPS, и это показатель для 28-ми ядерного решения!
Да, мы знаем, что на практике в Эльбрусе эти гигафлопсы плохо помогают на большинстве реальных задач от пользователей, но логично тогда поискать тот класс задач, где их можно всё-таки заиспользовать. И тут сразу напрашивается ответ – это High Performance Computing (HPC). Опять-таки, далеко не для всех задач в HPC количество гигафлопсов важно, но в общем и целом - это тот класс задач, где многие недостатки VLIW-архитектуры нивелируются, и Эльбрус может демонстрировать свой потенциал не только на бумаге. Тем более, что HPC вычисления, как правило, сопровождают достаточно квалифицированные специалисты, которые понимают специфику своих вычислений и по природе своей работы должны углубляться в особенности процессора и могут адаптировать программу под Эльбрус.
Из недостатков данного рынка применений для Эльбруса – он также крайне ограничен (сюда включаются как непосредственно суперкомпьютеры, так и часть пользователей, которым нужен запуск такого класса задач на своих машинах). Можно говорить о тысячах, возможно о десятках тысяч процессоров. Но всё равно это небольшие объёмы, которые будут держать реальную цену процессора очень высокой. Наличие вычислительного кластера, который хорошо считает только на определённых задачах, также не добавляет Эльбрусу плюсов в глазах потенциального клиента. Также здесь Эльбрус фактически вступает в конкуренцию с современными графическими картами, но т.к. в России они сейчас вообще не производятся, этот момент можно пока опустить.
Собственно, на мой взгляд, это все варианты, которые заслуживают обсуждения. Ситуации, когда приобретение процессора лишено экономической логики, рассматривать смысла не вижу - там возможно всё, что угодно.
Если внимательно посмотреть на вышенаписанное, то можно суммировать, что у Эльбруса, как представителя семейства VLIW-архитектуры, нет потенциала приблизиться к современным RISC/CISC процессорам по производительности на general-purpose нагрузках, даже с учётом доработок.
При этом возможные ниши для практического применения Эльбрусов существуют, но эти ниши достаточно узки и в большинстве случаев Эльбрусы в них могут быть безболезненно заменены обычными RISC/CISC процессорами.