Как стать автором
Поиск
Написать публикацию
Обновить

У VLIW длиннее x86: Itanium в шаге от величества, Эльбрус — подержите моё пиво, тайны PS2

Уровень сложностиСредний
Время на прочтение24 мин
Количество просмотров8.6K
Всего голосов 22: ↑21 и ↓1+25
Комментарии32

Комментарии 32

это архитектура, в которой несколько инструкций упаковываются в одно длинное машинное слово, выполняемое процессором за один такт.

Просто несколько risc-инструкций (компилятором) засовываются в одну длинную инструкцию что позволяет их за один такт считывать, но они не исполняются за один такт.

Все инструкции в таком пакете выполняются параллельно, что позволяет значительно повысить производительность

Повысить по сравнению с чем? Если по сравнению с голыми последовательными процессорами - да, а суперскаляры тоже исполняют инструкции параллельно и по сравнению с ними однозначно можно говорить только про более лучшую энергоэффективность.

Просто несколько risc-инструкций (компилятором) засовываются в одну длинную инструкцию что позволяет их за один такт считывать, но они не исполняются за один такт.

Это не так. Инструкции могут исполняться за один такт, если блоки процессора правильно загружены (а это уже зависит от зависимостей и уровня параллелизма в коде). Например, если у VLIW-процессора 4 блока ALU, а одно длинное слово содержит 4 арифметические операции, то все эти операции будут выполняться параллельно в один такт. Поэтому, собственно, VLIW-архитектура и зависит так сильно от компилятора, который должен правильно упаковывать инструкции.

Повысить по сравнению с чем? Если по сравнению с голыми последовательными процессорами - да, а суперскаляры тоже исполняют инструкции параллельно и по сравнению с ними однозначно можно говорить только про более лучшую энергоэффективность.

VLIW вполне себе может выигрывать суперскаляра в предсказуемых, хорошо оптимизированных задачах (DSP, мультимедиа, графика). Исполнение нескольких инструкций за такт (если компилятор справился) даёт преимущество при прочих равных.

Это не так. Инструкции могут исполняться за один такт, если блоки процессора правильно загружены

Строго говоря, инструкции не исполняются за один такт. Всегда есть конвейер, где есть стадии FETCH, DECODE и т.д., и стадия EXE тоже может занимать не один такт. Поэтому тут TC скорее прав - упаковка команд означает, что эти команды будут запущены по конвейеру синхронно, т.е. считаны и задекодированы вместе. Но дальнейшие их пути могут разойтись.

А smt не решает эту проблему? Понятно, что это будет другой поток, а не внутри одного потока, но по сути в многопоточных задачах будет так же эффективно и более гибко.

В голосовании нет правильного пункта: В реальном мире у алгоритмов обычно нет глубокого внутреннего параллелизма и по этому эффективно загружать вычислительные блоки VLIW не получится.

Второе - для создания эффективного кода недостаточно только исходников. Потому что по ним не понятно какие данные и в каком объёме будут обрабатываться. Вот цикл по всей коллекции. А сколько там элементов? Десять или миллиард? От этого зависит какой код будет наиболее эффективным. Суперскалярные процессоры худо-бедно умеют на лету перестраиваться под текущие данные. VLIW - нет.

В реальном мире у алгоритмов обычно нет глубокого внутреннего параллелизма и по этому эффективно загружать вычислительные блоки VLIW не получится.

В обработке сигналов, видеокодировании и других предсказуемых задачах довольно часто встречается глубокий параллелизм. Поэтому VLIW и живёт в DSP, GPGPU, специализированных вычислениях.

Второе - для создания эффективного кода недостаточно только исходников. Потому что по ним не понятно какие данные и в каком объёме будут обрабатываться. Вот цикл по всей коллекции. А сколько там элементов? Десять или миллиард? От этого зависит какой код будет наиболее эффективным. Суперскалярные процессоры худо-бедно умеют на лету перестраиваться под текущие данные. VLIW - нет.

Тут согласен с вами :) Поэтому и живём с суперскалярными процессорами.

Поэтому VLIW и живёт в DSP, GPGPU, специализированных вычислениях.

Ну да, живёт. А потом кто-то решил притащить это в CPU. В GPU кстати сейчас не осталось. Как шейдеры стали слишком сложные, так AMD на RISC перебежали.

Знаете, тут напрашивается патчик: "в реальном (падшем) мире".

Где гигантские дятлы бороздят просторы общества потребления, отмахиваясь "ещё памяти купите, а, и платформу обновите" на недоумение клиентов заказчика по поводу того, что старый сайт летал, а новый еле (если вообще) открывается.

Ну и если уж заговорили про "цикл по коллекции" -- если под коллекцией имеете в виду список, который технически связан указателями (т.е. "здесь" и впрямь не видать, сколько там ещё "впереди") -- то да; если массив (в т.ч. как индекс того списка), то нет.

Про особенности магического перестроения опять же расспрашивать не буду во избежание лишних слёз.

 вместо качественного кода, вдумчивого и оптимизированного, разработчики выбрали стратегию латать течи производительностью железа. Например, в x86 добавляли всё больше транзисторов для предсказания ветвлений, а на примере RTX 5000 видно, что железо больше не прибавляет по 30-50% производительности от поколения к поколению, и путь этот тупиковый. Оптимизация кода/компиляторов — вот куда всё и придёт, а не к гигантским чиплетам, многоядрам и многогерцам.

Как много раз упоминалось ранее в подобных дискуссиях, некоторые ситуации нельзя предвидеть с помощью статического планирования, компилятором. Но их можно увидеть и обыграть при динамическом планировании, непосредственно в железе. Так что одними компиляторами и оптимизациями кода вряд ли можно обойтись. Только лишь статическое планирование -- это путь к пессимистическим прогнозам и потерянной эффективности.


По поводу обилия железа, тушения пожаров транзисторами, и куда это могло бы привести: увеличение кол-ва транзисторов может дать дорогу вменяемой динамической реконфигурации под задачу и адаптивному железу. Возможно, это будет динамически реконфигурируемое железо в сочетании с just in time компиляторами и телеметрией, как пытаются сделать в этом проекте.

PS: чиплеты кстати скорее мелкие, и они больше про удешевление, повторное использование, лёгкое портирование, повышение выхода годных и разнообразие компоновки моделей. Т.е. они скорее ортогональны вопросам производительности.

Только лишь статическое планирование -- это путь к пессимистическим прогнозам и потерянной эффективности.

Для этого есть профилировка и подсказки компилятору ( inline restrict constexpr pragma итд). Динамическое планирование внутри процессора и оптимизация кода компилятором это совершенно разные задачи - динамический фронтенд не видит всей программы/процедуры у него нет на это ни ресурсов ни времен, он работает строго в маленьком окошке c пачкой команд которые ему нужно максимально эффективно расставить как в параллель так и в очередь. Он при всем желании не может заменить компилятор (ни статический, ни JIT) не нужно их противопоставлять.

Антогонистом динамике процессора является не компилятор, а большая структурированная супер-команда (ШК) в которой заранее все можно распланировать в ширь и в очередь, процессору остается только декодировать все это дело.

Плюсы и минусы есть у обоих подходов. Например жирные эльбрусовские команды со всем вот этим закодированным в них барахлом прилично отъедают кэш, а у интела/арма команды деленые+компактные и кэш занимают по минимуму. С другой стороны в эльбрусовскую ШК можно впихнуть что угодно например метки о том что код/данные следует закачать в L2, интелу-арму для этого придется добавлять новые инструкции вроде префетчера.
ШК требует полной синхронизации портов/каналов исполнения, тогда как в суперскаляре порты работают асинхронно. С другой стороны ШК позволяет из простого последовательного процессора недорого получить производительность уровня внеочередного процессора, пусть может не на всех задачах, но зато и без аппаратных уязвимостей.

В общем тут ворпрос уровня cmake vs cargo, ниразу не однозначный и на любой аргумент можно привести контраргумент (а то и не один).

Он при всем желании не может заменить компилятор (ни статический, ни JIT) не нужно их противопоставлять.

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

Антогонистом динамике процессора является не компилятор, а большая структурированная супер-команда (ШК) в которой заранее все можно распланировать в ширь и в очередь, процессору остается только декодировать все это дело.

Можно перефразировать и так, но смысл не меняется. ШК собирается с той позиции, с которой всё ещё невозможно увидеть некоторые ситуации, поэтому там либо придется делать пессимистические прогнозы, либо терять производительность на всевозможных простоях.

Профилирование не выглядит универсальным лекарством.

Противопоставляете утверждением о том что компилятор всегда исходит из писсимистичных сценариев, а вот мол процессор то в динамике больше видит.

Ну так и что из того что он видит? Он не может внести в код изменений на лету как тот же JIT, который как раз использует профилировку и налету перекомпилирует участки кода.

Процессор занимается своими задачами, он не может с кодом программы ничего сделать кроме как грузить и исполнять. Единственное что он может себе позволить из оптимизаций это в наглую попытаться разорвать лютую зависимости и поиметь профит, и этот "профит" проиграет хорошо оптимизированному коду всего в 5-10 раз, а не в 20-40 как на эльбрусе например.

В качественном коде и качественном компиляторе нуждаются абсолютно все. Эльбрус, как и другие vliw процессоры, выделяет то что они крайне чувствительны к качеству кода который компилятор выдает специально для них. Об этом всегда и были разговоры, мол это требует совершенно других компиляторов (в том числе JIT) что просто ведет платформу в условный тупик. Когда оно мутировало в то что чуть ли не в железе все оптимизации происходят у внеочередных суперскалярах я не понимаю.

Профилировка помогает не исходить из писсимистичных либо оптимистичных сценариев, а вырабатывать конкретную стратегию по оптимизациями на основе обрабатываемых данных. Вполне универсальный инструмент, который используется не только в компиляторах но и в кодировании видео.

А теперь к главным фишкам Эльбруса — перед нами не просто VLIW, а полная программная модель. Это значит, что функционал, который в других архитектурах как правило работает аппаратно, здесь выполняются с помощью микрокода — низкоуровневого программного слоя, который управляет процессором.

Эльбрусы используют автоматическое динамическое планирование команд на уровне микрокода, что на практике снижает зависимость от компилятора (привет, Itanium или классический VLIW), улучшает предсказуемость исполнения и снижает нагрузку на компилятор. Даже если компилятор неидеально оптимизировал код, процессор всё ещё может самостоятельно переупорядочить инструкции для эффективного исполнения. 

Вот эта особенность и позволяет Эльбрусам эффективно работать с неоптимизированным для VLIW кодом, включая инструкции x86. Динамическое планирование команд в Эльбрусе — это ключевой момент архитектуры, попытка решить главный недостаток VLIW. Itanium пытался в спекулятивное исполнение и предсказание ветвлений (EPIC), но подход Эльбруса кажется перспективнее.

Здесь написана полная ерунда. Ничего такого в Эльбрусе нет - там классический статический VLIW, который стоппится в случае невозможности исполнить все инструкции в бандле. Никакого микрокода и динамического планирования там нет, непонятно, откуда вы взяли эту ересь.

И кстати, как раз Итаниум шёл по пути динамического планирования, когда начал внедрять элементы динамики во VLIW. Собственно,они потому и назывались EPIC, а не VLIW, с претензией на то, что просто указывают параллелизм в команде, а как она исполняется - дело отдельное.

Здесь написана полная ерунда. Ничего такого в Эльбрусе нет - там классический статический VLIW, который стоппится в случае невозможности исполнить все инструкции в бандле. Никакого микрокода и динамического планирования там нет, непонятно, откуда вы взяли эту ересь.

Вот пример динамического планирования в Эльбрусе: "https://елбрус.рус/руководство-по-эффективному-программированию-на-платформе-эльбрус"

Чтобы избежать антизависимостей, которые которые останавливают выполнение команд в бандле, у Эльбруса есть явное переименование регистров (тут по ссылке это базированные регистры). Процессор использует цикл переименования (вращение окна регистров), что позволяет следующей итерации цикла использовать новый регистр без конфликта. Переименование программное, управляется компилятором.

Ну вы же сами пишите:

Переименование программное, управляется компилятором

Описанный механизм базированных регистров - это просто возможность работать с регистровым файлом как с массивом. Но это всё статически определяется компилятором - какое окно выделить, насколько регистров крутить. Никакого динамического планирования или тем паче микрокода это не подразумевает.

Микрокода в эльбрусах нет; а в целом Маслова воспринимать с доверием не стоит -- про те же предикаты, точнее, их отсутствие он тупо врёт (процитировав и сразу "опровергнув"). Маякнуть, что ли, опять Рубанову :-/

Но высасывать что-то из пальца и домысливать, не выяснив/переспросив -- не менее гибельный путь, потому что искренне заблуждающийся способен ввести в заблуждение не меньше людей, чем активно и целенаправленно лгущий; хотя бы в том же @e2k_chat стоило провентилировать основные тезисы своей статьи, а то и черновик.

А отвечать нам -- каждому за свои косяки -- всенепременнейше.

В современных Эльбрусах (например, Эльбрус-8С, Эльбрус-16С) есть 256 64-битных регистров общего назначения

Во-первых, там всё же 80-ти битные регистры были. Во-вторых, начиная с Эльбрус-8СВ там они уже 128-ми битные.

В ранних Эльбрусах-2С+? Даже там там регистры общего назначения были 64-битными (как и всегда в Эльбрусах). Вещественные (FPU), да, действительно были 80-битными.

Опять-таки, вы же сами пишите:

есть 256 64-битных регистров общего назначения (разделения на целочисленные и вещественные регистры, как в Itanium, нет)

Т.е. там общие регистры для целочисленной арифметики и для вещественной, это верно. И они размером 80-бит начиная с самой первой версии Эльбруса, просто не все команды могут эту ширину использовать. Эти 80-бит были обусловлены необходимостью поддержки 80-битных регистров в x87. На самом деле там ещё пару бит на теги есть, но да ладно, программно они не видны, поэтому не считается.

Так то в эльбрусе 192 регистра в регистровом файле + 32 предикатов в предикатном файле + 32 глобальных.

регистровые файлы продублированы в кластерах и технически там 448 регистров.

Помимо этого согласно документации каждый %dr0 делится на %r0 и %r1 (hi и lo часть), так что субъективно там 448 32битных регистра в одном кластере.

Со 128и битными %qr не очень понятно, они сплитуются так же или там нижняя часть это %dr регистр а старшая отдельно и используется только с векторными устройствами.
Но может быть сплитуются все, тогда в современных эльбрусах получается аж 856 32битных регистра в локальной части и еще 128 в глобальной. Хотя в одной процедуре все равно можно использовать только 120.

Так, давайте не путать людей.

До Э8СВ - логический регистровый файл это набор 80-ти битных регистров в количестве 256 штук (32 глобальных регистра и 224 "процедурных"). Ещё 4 бита на теги (по 2 на 32-битный регистр), но они программно не видны. Физически там действительно есть 2 кластера, где есть копия для каждого регистра в каждом кластере, т.е. физически регистров в 2 раза больше. Но это не видно программисту никак.

Начиная с Э8СВ - логический регистровый файл это набор 128-ми битных регистров в количестве 256 штук. Ещё 8 бит на теги. Есть ли там дублирование на 2 физических регистровых файла для каждого кластера я точно сказать не могу. Где-то читал, что вроде от этого отказались, но тут не возьмусь утверждать что-то.

и 224 "процедурных"

так то оно так, но в них входят 32 однобитных предиката ( тоже с тегами но сколько битов на каждый я не могу сказать), поэтому все таки 192 общих-числовых.

Есть ли там дублирование на 2 физических регистровых файла для каждого кластера я точно сказать не могу.

Убрали кластеры, об этом есть как устные разъяснения мцст (вроде бы применили кастомный дизайн блоков регистровых файлов), так и обзор спила кристала от House of что-то там, где видно что кластеров больше нет.

В общем я о чем - 64 битная часть в регистрах полноценная, к старшей и младшей части можно обращаться через одинарное представление любыми операциями, а +16битное расширение (превращающее его в 80и битный), к нему никак отдельно обратится нельзя, оно строго для умножения 64битных с переполнением и 80и битной вещественной арифметики. Что то мне подсказывает что в 8СВ вот это расширение регистра с конотацией %xr просто увеличили до [64 [32 32]] засчет того что убрали лишний кластер освободив кучу места при том же техпроцессе и размере кристала.
Но есть так же предположение что в 16С все таки сделали полноценный четверной регистр, на это косвенно указывает новая коннотация %qr иначе какоеоно квадро если не сплитуется на четыре одинарных.

так то оно так, но в них входят 32 однобитных предиката ( тоже с тегами но сколько битов на каждый я не могу сказать), поэтому все таки 192 общих-числовых.

Нет, речь именно об обычных регистрах, я же чётко написал что они 80-ти (128-ми) битные, и их 256 суммарно (32+224). Предикатные регистры отдельно, о них сейчас вообще нет речи

В остальном написанном тоже много ошибок, но да ладно, пусть в конце концов сотрудники МЦСТ проводят бесплатные лекции. Базу я выше написал, опирайтесь на неё.

Итак, помимо очевидного (в честь горы) есть и другой вариант расшифровки названия: «Elbrus» — акроним от англ. ExpLicit Basic Resources Utilization Scheduling — «явное планирование использования основных ресурсов»

А я слышал что от El Burrows

в институте Лебедева проект Эльбрус-1 первоначально назывался Чигет, проект Эльбрус это был Эльбрус-2, ребята на лыжах любили кататься, в том числе на Кавказе, отсюда название, слухи это уже позже,

про Эльбрус-1 на подводной лодке это фантазии, корабельный вариант действительно был

Закрытость и проприетарность технологий полезны для кибербеза,

Фатальное заблуждение.

security through obscurity

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

Любой современный процессор прекрасно поймёт, что эти последовательные в коде команды можно выполнять параллельно.

В голосовалке нет пункта, что VLIW ущербна сама по себе

А можете рассказать подробнее -- как именно "прекрасно поймёт"? В детстве дальше сумматора с регистром разбираться уж не полез, а тут, смотрю, цельный эксперт по декодерам (и мож ещё чему вроде дырок и потребления).

Что до ущербности -- держите таблеточку тут же рядом да не кушайте с масловской лопаты больше то, чем он неущербных потчует: http://habr.com/ru/post/575302

// отправлено с моего "Эльбрус-16С"

Соглашусь с одним из комментаторов: за исключением узкоспециализированных вычислительных алгоритмов, большинство программ плохо ложатся на VLIW.

Взять тот же PostgreSQL - ветвление чуть ли не каждая третья-четвертая инструкция. А между ветвлениями простые вычисления с линейной зависимостью данных. Параллелизатору просто не где разбежаться. А вот спекулятивному выполнению и переупорядочению инструкций обычных (x86-64/ARM) процессоров - вполне.

Конечно, можно написать с нуля базу с расчетом на VLIW. Но кто этим заниматься будет?

А когда переходим к бизнес-приложениям, то там в принципе вычислений по минимуму, а 90% - это проверки бизнес правил. Что там собрались утрамбовывать в «широкие инструкции»? Не чего.

Но в качестве математических сопроцессоров и DSP, конечно же VLIW хороши.

Так что: Эльбрус действительно хороший вычислитель. Но ему не хватает процессора общего назначения в пару.

Наверняка про это уже написали, но:
> Софт, написанный для конкретного VLIW-процессора, может быть несовместим [...]
Знаете, у меня сложилась проверка на нацизм: если текст после замены "русский" на "еврейский" вдруг становится нацистским -- значит, он им и был.
Попробуйте в том фрагменте заменить VLIW на RISC и, тыскыть, окинуть взглядом результат :)

Можно добавить и ещё одну проблему VLIW: процессор не всегда живёт и работает в тепличных условиях.

Если это DSP-процессор, работающий в связке в процессором общего назначения, условия для DSP будут близки в тепличным: всю побочную работу выполняет процессор общего назначения, а DSP остаётся лишь перемалывать данные. А вот если VLIW-процессор оказывается единственным в системе, сразу возникает куча отвлекающих факторов.

В частности, даже если компилятор всё верно предсказал, сформировал необходимые команды предзагрузки данных для их последующего использования и т.д., эти данные вовсе не обязательно к моменту необходимости в них окажутся для процессора доступными -- и тогда он вынужден будет стоять и ждать. А недоступными они могут, например, оказаться из-за того, что параллельно выполняются интенсивные операции ввода-вывода, и память постоянно занята обменом с контроллерами дисков и т.д. и т.п., оставляя процессор "на голодном пайке". Традиционный суперскалярный процессор с внеочередным выполнением команд в такой ситуации может продолжать работу, пока не упрётся в некие ограничения (команда, для которой нет данных, будет находиться в ожидании, но последующие будут выполняться, если они не завязаны с ожидающей командой), но традиционный VLIW будет стоять. Нет, конечно, и там можно реализовать внеочередное выполнение и т.д. и т.п. -- но это напрочь убьёт относительную простоту и энергоэффективность.

В общем, идея интересная, но именно что нишевая -- не для задач общего назначения.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий