LINUX.ORG.RU

Сбербанк провёл испытания процессоров «Эльбрус»

 , , , ,

Сбербанк провёл испытания процессоров «Эльбрус»

0

3

Сбербанком было проведено серверное тестирование на процессорах «Эльбрус». Итогом стала констатация того, что в данный момент предоставленное МЦСТ оборудование технически не соответствует запросам и ожиданиям корпорации.

Представитель лаборатории новых технологических решений Сбербанка Антон Жбанков дал следующие комментарии: «Технические выводы достаточно простые: очень слабо для сравнения с Intel Xeon — мало памяти, медленная память, мало ядер, мало частоты. Функциональные требования катастрофически не выполнены».

Сбербанк проводил изучение серверов по различным методикам. Приведенные критические оценки в первую очередь относятся к итогам функционального тестирования по методике Sberinfra на соответствие корпоративным эксплуатационным требованиям банка.

В результате тестирования, как отметил Жбанков, «чуда не произошло» — серверы показали соответствие 7 из 44 параметров («наличие лапки кабель-менеджмента, наличие рельсов, наличие индикации каждого элемента, наличие удаленного управления» и пр.) — 16%.

Изделия на российских чипах уступили зарубежному конкуренту по всем параметрам, однако полученные результаты сотрудников Сбербанка все же «неожиданно и очень приятно» удивили. «Мы ожидали, что разница будет не в разы, а в 20-30 раз, — отмечает Жбанков. — Для нас это реально удивительно». Вторым фактором удивления для тестировщиков стал вывод о том, что перед ними оказался законченный продукт.

Фрагмент с выступлением руководителя лаборатории новых технологических решений «Сбера» Антона Жбанкова на партнерской конференции АО «МЦСТ» по поводу проведения этого тестирования доступен по данной ссылке (таймкод уже применён: 2:14:44).

Из комментариев МЦСТ: «Для цели тестирования Сбербанком было разработано и передано макетное приложение. Для этого макетного приложения за счет доработки Java-машины и подбора опций улучшили среднее время отклика на процессоре “Эльбрус-8С” с исходных 24 мс до 4 мс (в шесть раз), при этом на X86 (Соге i7-9700 CPU 3 GHz) оно получилось 3 мс».

8-ядерный российский процессор «Эльбрус-8С» на архитектуре E2K выпускает АО «МЦСТ». У данного производителя есть и другие более современные процессоры — «Эльбрус-8СВ» и «Эльбрус-16С», который еще не вышел на рынок. В планах компании выпустить «Эльбрус-32С». Планируется, что «Эльбрус-32С» будет создан по технологии 7 нм, а первые рабочие образцы российского 32-ядерного процессора появятся в 2025 году.

>>> Подробное описание новости на cnews.ru

★★★

Проверено: Harald ()
Последнее исправление: a1batross (всего исправлений: 9)

Ответ на: комментарий от uin

Ты так и не посчитал. Ну да ладно. Я понимаю, что читать язык ассемблера e2k не такая приятная задача. Особенно во втором случае…

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

Я уже писал в чём разница, и не раз. Пока Эльбрус чего-то ждёт, OoOE работает.

по сути мешают работать - это то к чему надо стремиться ты считаешь?

Ты же сам только что кичился, что в Эльбрусе это фишка. xD

Давай посмотрим с другой стороны. Как в Эльбрусе спекулятивно исполнить системный вызов? :)

numas13
()
Ответ на: комментарий от uin

А, ну так тут вообще gcc все свернул в константы

Какие константы? Это jump table. lcc так же будет делать для больших switch.

numas13
()
Ответ на: комментарий от numas13

Ты так и не посчитал. Ну да ладно. Я понимаю, что читать язык ассемблера e2k не такая приятная задача. Особенно во втором случае…

Наоборот мне он больше нравится чем интелловский и уж тем более армовский.

Я уже писал в чём разница, и не раз. Пока Эльбрус чего-то ждёт, OoOE работает.

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

Давай посмотрим с другой стороны. Как в Эльбрусе спекулятивно исполнить системный вызов? :)

Никак. Но его можно 1. подготовить заранее 2. это полностью безопасно и нет никаких причин его не использовать, тем более пытаться криво косо мешать ему это сделать.

uin ★★★
()
Ответ на: комментарий от numas13

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

uin ★★★
()
Ответ на: комментарий от uin

Наоборот мне он больше нравится чем интелловский и уж тем более армовский.

Но ты всё ещё не посчитал такты…

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

Ты просто не в состоянии понять о чём идёт речь.

Никак. Но его можно 1. подготовить заранее 2. это полностью безопасно и нет никаких причин его не использовать, тем более пытаться криво косо мешать ему это сделать.

Можно пример как ты «подготовишь заранее» внутренности системного вызовы в пользовательском коде?

numas13
()
Ответ на: комментарий от uin

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

Дело в другом. В Эльбрусе jump table будет хуже если данные всё же будут в L1d для небольшого switch. Но я же не зря тебя прошу такты посчитать, когда посчитаешь то сразу поймёшь о чём я пишу.

numas13
()
Ответ на: комментарий от numas13

Но ты всё ещё не посчитал такты…

Сразу после того как ты их посчитаешь для интела

Ты просто не в состоянии понять о чём идёт речь.

Аналогично.

Можно пример как ты «подготовишь заранее» внутренности системного вызовы в пользовательском коде?

Команда disp для чего сделана по твоему? Она прогружает код и даже декодирует и загружает в конвеер несколько инструкций оттуда параллельно с основным потоком исполнения.

Дело в другом. В Эльбрусе jump table будет хуже если данные всё же будут в L1d для небольшого switch. Но я же не зря тебя прошу такты посчитать, когда посчитаешь то сразу поймёшь о чём я пишу.

~20 тактов по самым скромным подсчетам, и? Что я должен из этого понять?

uin ★★★
()
Ответ на: комментарий от uin

Сразу после того как ты их посчитаешь для интела

Cдаёшься?

Команда disp для чего сделана по твоему? Она прогружает код и даже декодирует и загружает в конвеер несколько инструкций оттуда параллельно с основным потоком исполнения.

И как же эти инструкции исполняются спекулятивно? В твоём мире условный ldd исполняется в декодере? xD

~20 тактов по самым скромным подсчетам, и? Что я должен из этого понять?

Так и быть. Дам тебе подсказку. Процессор Эльбрус-16С. Посчитай для первого case в первом случае. Потом посчитай такты для ldd+motvd+ct+ldd+ldw+adds для jump table.

numas13
()
Ответ на: комментарий от numas13

Cдаёшься?

Глупость непобедима, бороться против нее не вижу смысла.

И как же эти инструкции исполняются спекулятивно? В твоём мире условный ldd исполняется в декодере? xD

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

посчитай такты для ldd+motvd+ct+ldd+ldw+adds

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

uin ★★★
()
Ответ на: комментарий от uin

Глупость непобедима, бороться против нее не вижу смысла.

Пусть каждый останется при своём. Я с глупостью, а ты с невежеством.

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

Погоди я спрошу у @uin.

@uin мешают процессору прогружать функции, по сути мешают работать

Слушай. Он пишет, что отсутствие спекулятивности в системных вызовах мешает работать процессору. Что будем делать? :)

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

А ты забавный. Или лучше невнимательный?

@numas13 Я написал, что это будет только в случае ошибки предсказателя.

Я так понимаю, что подсчитанные такты ты не собираешься написать? Боишься что горькая правда про Эльбрусы вылезет наружу? Хотя, я то и сам не лучше, уже давно мог бы написать, но так вышло веселее. Нет, ты не подумай, если бы я хотел топить Эльбрусы, я бы это уже сделал. Просто ты и сам меня провоцируешь на эту нездоровую дискуссию. :)

numas13
()
Ответ на: комментарий от numas13

Я так понимаю, что подсчитанные такты ты не собираешься написать?

Я то напишу, просто ты тут же сольешься и ради чего спрашивается было разбирать вот эту лапшу?

f(int, int**):
    { disp  %ctpr2, .L6 }    ~ a-1
    { return        %ctpr3 } ~ a-2
    { disp  %ctpr1, .L200}   ~ a-3
    { }                      ~ a-4
    { }                      ~ a-5
    { ct %ctpr2 ? ~%pred0  } ~ a-6 ? => b-7
    { }                      ~ a-7
    { }                      ~ a-8
    { ct %ctpr1 ? %pred7 }   ~ a-9 ? => c-10
    { nop 2 }                ~ a-[10...12]
    { }                      ~ a-13
    { ct   %ctpr3 ? %pred2 } ~ a-14 ? => выход
    { ct   %ctpr3 ? %pred8 } 
    { ct   %ctpr3 ? %pred6 } 
    { ct   %ctpr3 ? %pred0 } 
    { ct   %ctpr3 ? %pred9 } 
    { ct   %ctpr3 ? %pred5 } 
    { ct   %ctpr3 ? %pred4 } 
    { ct   %ctpr3 ? %pred3 } ~ a-21 ? => выход
.L6:
    { return        %ctpr3 } ~ b-7
    { disp  %ctpr2, .L200 }  ~ b-8
    { }                      ~ b-9
    { }                      ~ b-10
    { }                      ~ b-11
    { }                      ~ b-12
    { ct  %ctpr2 ? %pred9 }  ~ b-13 ? => e-14
    { ct  %ctpr3 ? ~%pred11} ~ b-14 ? => выход
    { ct  %ctpr3 ? ~%pred6 } ~ b-15 ? => выход
    { ct  %ctpr3 ? ~%pred8 } ~ b-16 ? => выход
    { nop 1 }                ~ b-[17...18]
    { nop 1 }                ~ b-[19...20]
    { ct  %ctpr3 ? %pred0 }  ~ b-21 ? => выход
.L200:
    { nop 4; return  %ctpr3 }~ c-[10...14] | e[14...18]
    { nop 4 }                ~ c-[15...19] | e[19...23]
    { nop 1 }                ~ c-[20...21] | e[23...24]
    { ct    %ctpr3 }         ~ c-22 | e-25 => выход

uin ★★★
()
Последнее исправление: uin (всего исправлений: 1)
Ответ на: комментарий от numas13

Теперь для jump table.

Посчитал тебе защеку, проверь.

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

uin ★★★
()
Ответ на: комментарий от uin

Посчитал тебе защеку, проверь.

Как нам в детстве говорили: «У кого что болит, тот о том и говорит». :)

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

То есть теперь уже код виноват… Любой спор про Эльбрусы всегда этим заканчивается. Виноваты все вокруг, но не Эльбрус. :)

Конечно же это всего лишь демонстрация, в реальности может быть хуже/лучше. Просто не все осознают стоимость «бистро-бистро» в Эльбрусе, а это наглядная демонстрация.

// в зависимости от µarch
// код и данные уже в L1
//   с ошибкой ~27-31 такта  (24-27 на возврат из процедуры)
// без ошибки   ~8-10 тактов (3-5 на возврат из процедуры)
f(int, int**):
        sub     edi, 97                    -+ predict window 1
        cmp     edi, 14                     |
        ja      .L2                         |
        jmp     [QWORD PTR .L4[0+rdi*8]]   -+ miss
.L4:
        .quad   .L17
        .quad   .L8
        .quad   .L16
        ...
        .quad   .L3
.L8:
        mov     rax, QWORD PTR [rsi+128]
.L18:
        mov     eax, DWORD PTR [rax]       -+ predict window 3
        add     eax, 1                      |
        ret                                -+
.L16:
        mov     rax, QWORD PTR [rsi+256]   -+ predict window 2
        jmp     .L18                       -+
.L15:
        ...

Для jump table в Эльбрусе будет примерно ~32-36 тактов. Ну тут как бы и нет ничего удивительного. Разница в том, что Эльбрус не может быстрее, т.к. нет предсказателя и OoOE. Наносекунды для x86 и Эльбруса думаю и сам сможешь посчитать.

numas13
()
Ответ на: комментарий от numas13

То есть теперь уже код виноват…
Конечно же это всего лишь демонстрация,

10 актов (в самом оптимистичном случае) для того что бы сложить элемент массива - ты считаешь это нормальный код? Но даже не в этом он говенен, а в том что он ровным счетом ничего не показывает - какая то функция которая принимает какое то значение и делает по нему выборку. Если это значение может выбираться например в зависимости от локали пользователя и тогда эта ситуация predictable и бранчпредиктор здесь будет гораздо лучше (но не так уж чтобы лучше jit который бы просто холодные ветки выкинул совсем а add синлайнил одной операцией), а если эта функция в цикле какие то данные обрабатывает, тот тут ситуация уже неодназначная, но не сказать что с таким кодом она может быть в принципе для кого-то хорошей.

Для jump table в Эльбрусе будет примерно ~32-36 тактов. Ну тут как бы и нет ничего удивительного. Разница в том, что Эльбрус не может быстрее, т.к. нет предсказателя и OoOE.
// с ошибкой ~27-31 такта (24-27 на возврат из процедуры)
// без ошибки ~8-10 тактов (3-5 на возврат из процедуры)


И почему тогда интел не смог? У него же есть и то и другое.

Вопрос риторический.

uin ★★★
()
Ответ на: комментарий от uin

10 актов (в самом оптимистичном случае) для того что бы сложить элемент массива - ты считаешь это нормальный код?

Ты ворвался в мою дискуссию с другим человеком и даже не удосужился ознакомится с ней перед тем как начинать что-то доказывать? Речь была про доп. нагрузку на процессор из-за спекулятивного исполнения в e2k.

numas13: Когда в e2k начинается работа с памятью, то всё становится намного веселее. Часть/части базовых блоков начинают мигрировать выше нагружая процессор бесполезной работой, если исполнение не лежит через эту ветку. Но с другой стороны это повышает загруженность ШК и избавляет от и без того медленных ветвлений в e2k.

numas13: https://ce.mentality.rip/z/9Ks6Kv

numas13: В e2k всегда будет обращаться в память, даже если эту ветку не надо исполнять. Кеш-промахи будут в любом случае. :)

monk: При аппаратном спекулятивном выполнении тоже. Причём при аппаратном ещё и уязвимости типа Spectre в комплекте.

numas13: Если предсказатель ошибся, а в e2k ВСЕГДА если так решит компилятор. Разница в том, что OoOE процессор не ждёт пока код исполнится, декодировал за 1-2 такта в этом конкретном случае и пошёл обратно в вызывающую процедуру. В Эльбрусах вынужден ждать (если очень везучий то до +100 тактов или больше) и ничего не делать.

И ТУТ ВРЫВАЕТСЯ @uin

uin: Ты только что говорил про бесполезную работу которую делает эльбрус и постоянную нагрузку на память, и тут же выдаешь это за достоинство в суперскаляре. В in-order VLIW эта нагрузка на память управляемая, в суперскаляре нет - вот и вся разница.

numas13: Я написал, что это будет только в случае ошибки предсказателя.

numas13: Давай рассмотрим простейший случай.

И понеслась…

И почему тогда интел не смог? У него же есть и то и другое.

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

Да простят меня боги ЛОРа за эти цитаты…

numas13
()
Ответ на: комментарий от numas13

Ты ворвался в мою дискуссию с другим человеком и даже не удосужился ознакомится с ней перед тем как начинать что-то доказывать? Речь была про доп. нагрузку на процессор из-за спекулятивного исполнения в e2k.

Так потому и ворвался что если ты не видишь (явно в ассемблере) спекулятивных операций это не значит что их нет.
Они есть, без спекулятивного исполнения никакой процессор не может даже начать грузить значение по указателю пока не узнает куда надо прыгнуть. Почему? Потому что все указатели кроме выбранного могут указывать на nullptr, программа это допускает а процессор должен корректно отрабатывать. Без спекулятивного исполнения процессор - тормоз, говоришь ОоО подразумеваешь спекулятивное исполнение. Что такое Е я не знаю, по теме суперскаляров за 30 лет ничего особо нового не сделано (зато по теме vliw постоянно что то выходит и нет, не у одной мцст)

uin ★★★
()
Ответ на: комментарий от uin

facepalm.jpg

Серьёзно. Вот перечитай цитату из предыдущего сообщения.

monk: При аппаратном спекулятивном выполнении тоже. (речь про OoOE)

numas13: Если предсказатель ошибся, … (речь про OoOE)

Это уже реально начинает походить на какую-то комедию. :)

numas13
()
Ответ на: комментарий от uin

Так потому и ворвался что если ты не видишь (явно в ассемблере) спекулятивных операций это не значит что их нет.

Там речь шла про то, что при аппаратной спекуляции затык операции из-за отсутствия в кэше не блокирует текущее выполнение. Теоретически можно такое же изобразить и на Эльбрусе, но тогда придётся делать rbranch на каждое спекулятивное чтение, что, во-первых, удвоит код, а во-вторых, если верить numas13, то rbranch очень дорогой (5 тактов).

monk ★★★★★
()
Ответ на: комментарий от monk

Мы многое успели обсудить. :)

Если МЦСТ таки запилит в v7 нормальный предсказатель, то это не будет такой уж и теорией. Во всяком случае эта идиотская связка из prepare+ct (считай что тоже самое что и delay slots, только немного лучше) канет в Лету.

numas13
()
Ответ на: комментарий от numas13

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

uin ★★★
()
Ответ на: комментарий от uin

facepalm.jpg :)

Я ещё раз повторяю, что речь шла про лишнюю нагрузку на исполнительные устройства. Если предсказатель угадал, то никакой лишней работы не было. Если не угадал, то эта ветка лишняя.

Теперь скажи мне сколько лишних веток тут.

Желательно ещё раз внимательно перечитай краткую выжимку.

numas13
()
Ответ на: комментарий от monk

при аппаратной спекуляции затык операции из-за отсутствия в кэше не блокирует текущее выполнение


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

Теоретически можно такое же изобразить и на Эльбрусе, но тогда придётся делать rbranch

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

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

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

uin ★★★
()
Ответ на: комментарий от numas13

эта идиотская связка из prepare+ct

Разумеется не канет и она не идиотская. У твоего интела на пол ядра фронтенд который декодирует команды в микроопы уже на этом этапе прикручен бранчпредиктор который палит команды перехода и начинает тащить код бранча. Как ты это будешь ловить без фронтенда? Во время декодирования со штрафами в 2-3 такта? И вот тут то тебе и приходят старые-добрые команды подготовок которые будут уведомлять предсказатель заранее что возможен переход по такому то адресу, просто ctpr регистров можно сделать побольше и 6 тактов выжидать будет не нужно.

uin ★★★
()
Ответ на: комментарий от uin

Разумеется не канет и она не идиотская.

Ещё какая идиотская…

У твоего интела на пол ядра фронтенд который декодирует команды в микроопы уже на этом этапе прикручен бранчпредиктор который палит команды перехода и начинает тащить код бранча.

Так! Когда успели передать мне во владение Intel? Где бумаги!? xD

Как ты это будешь ловить без фронтенда? Во время декодирования со штрафами в 2-3 такта? И вот тут то тебе и приходят старые-добрые команды подготовок которые будут уведомлять предсказатель заранее что возможен переход по такому то адресу, просто ctpr регистров можно сделать побольше и 6 тактов выжидать будет не нужно.

В очередной раз убеждаюсь, что МЦСТ не нужны никакие критики с такими «защитниками». xD

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

Вообще очень странно с твоей стороны так рьяно оптимизировать ещё не выполненные ни разу безусловные переходы. Ты точно знаешь как работает предсказатель? Вон в «моём Intel» вообще случайно предсказывает в первый раз. :)

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

numas13
()
Ответ на: комментарий от numas13

Но основной функционал по подготовке перехода канет в Лету.

Потому что он монстроузен, у них там по факту фронтенд должен уметь декодировать 4 команды по 512бит одновременно что бы оно работало.

Вообще очень странно с твоей стороны так рьяно оптимизировать ещё не выполненные ни разу безусловные переходы. Ты точно знаешь как работает предсказатель?

Безусловный переход не надо что ли в конвеер готовить? Надо подождать пока инструкция перехода до конца дойдет выполнится и после этого только начать забивать пайплан его инструкциями?

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

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

VLIW просто как очередной логичный этап развития вот этого всего.

uin ★★★
()
Ответ на: комментарий от uin

Потому что он монстроузен, у них там по факту фронтенд должен уметь декодировать 4 команды по 512бит одновременно что бы оно работало.

МЦСТ хочет заменить это барахло на нормальный предсказатель. Что тебе не нравится?

Безусловный переход не надо что ли в конвеер готовить? Надо подождать пока инструкция перехода до конца дойдет выполнится и после этого только начать забивать пайплан его инструкциями?

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

VLIW просто как очередной логичный этап развития вот этого всего.

Context-510
branch predictor
superscalar
3-decode
3-issue
in-order

Объяснять или ты сам разберёшься?

Вообще складывается такое впечатление, что ты залез в криокамеру где-то в конце 80-х и только недавно вылез на свет Божий. :)

numas13
()
Ответ на: комментарий от uin

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

У Эльбруса есть регистровое окно. Не хуже, чем 16 фальшивых регистров.

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

http://www.mcst.ru/files/5ed39a/dd0cd8/50506b/000000/elbrus_prog_2020-05-30.pdf

monk ★★★★★
()
Ответ на: комментарий от numas13

Но основной функционал по подготовке перехода канет в Лету.

Уже есть ibranch. Если он будет отрабатывать в 1 такт (а технических препятствий нет), то ct останется нужен только для вычислимого goto и перехода по произвольному адресу из переменной.

monk ★★★★★
()
Ответ на: комментарий от monk

Да, верно. В e2k нет другого способа выполнить косвенный переход. Но есть нюансы.

Где CS0, CS1, SS, ALS слоги по 32 бита каждый и ALES полуслог в 16 бит.

  • В циклах очень часто встречается SS для коротких операций (abn, alc, APB, etc). Если использовать ibranch вместо связки disp=>ct, то это потребует дополнительный слог, а размер ШК ограничен в 512 бит. Так что смысл в такой схеме имеется, но не из-за подготовки перехода, а для сокращения кода в циклах.

    • ibranch = CS0+SS
    • disp=>ct = CS0=>SS
  • Вызов процедуры можно сделать через связку disp/movtd=>call (CS0/ALS+ALES=>SS+CS1).

  • Системный вызов можно сделать через связку sdisp=>call (CS0=>SS+CS1).

  • Упомянутый тобой случай, movtd=>ct для косвенных переходов (ALS+ALES=>SS).

  • Через %ctpr2 подготавливается программа для APB ldisp=>bap (CS0=>SS).

  • Возможно ещё что-то, что я запамятывал.

В остальных же случаях в нём не будет большого смысла. Хотя можно было бы сделать как-то так (disp_always выдуманный):

disp_always %ctpr1, label
не позже 5 тактов спустя
ct %ctpr1

В этом случае можно было бы избежать пузырей в конвейере для неизвестных безусловных переходов если имеется полезная нагрузка (опуская вопрос обратной совместимости подобного решения и эффективности/необходимости этого подхода). Но в e2k не обязательно выдерживать точную задержку. Может быть и такая ситуация:

disp %ctpr1, label
30 тактов спустя
ct %ctpr1

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

disp %ctpr1, label
5 тактов спустя
ct %ctpr1 ? %pred0

Скажем так, то как e2k была спроектирована изначально будет вставлять палки в колёса на протяжении всей жизни этой архитектуры. Я считаю, что E2K ISA необходимо полное переосмысление. :)

numas13
()
Ответ на: комментарий от numas13

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

Если есть предсказатель, то то же самое, что и Intel на условный переход. В смысле, угадываем %pred0 по предыдущему переходу.

http://mcst.ru/doc/130621/Shabanov.pdf

monk ★★★★★
()
Ответ на: комментарий от monk

Ты не уловил суть.

numas13: В этом случае можно было бы избежать пузырей в конвейере для неизвестных безусловных переходов

Я написал конкретно про использование связки disp=>ct для устранения пустышек в конвейере для ещё не встреченных безусловных переходов. Технически это можно сделать с 1 доп. конвейером, что само по себе глупая затея не стоящая выеденного яйца.

numas13: В остальных же случаях в нём не будет большого смысла.

В остальных случаях преимущества перед ibranch у связки из disp=>ct нет, т.к. обычно больше кода (но может быть так же) и не менее 2 тактов на исполнение.

numas13
()
Ответ на: комментарий от numas13

Я не понимаю, что мешает делать разбор команд вперёд.

Если Intel читает вперёд на сотню команд (в том числе после jmp), то что мешает аналогично Эльбрусу читать вперёд, включая ibranch (и делая выполнение ibranch в один такт)?

monk ★★★★★
()
Ответ на: комментарий от monk

Я не понимаю, что мешает делать разбор команд вперёд.

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

Как это выглядит сейчас.

J: ibranch label
...
L: label: ops...

    A F0 F1  S  D  B
 0  J                 << адрес ibranch
 1     J              << загрузка 1
 2        J           << загрузка 2
 3           J        << распаковка ШК
 4              J     << декодирование
 5                 J  << тут процессор понимает что это ibranch
 6  L                 << начинается исполнение label

Т.к. сейчас в Эльбрусах нет предсказателя, то у него вырисовывается та самая задержка у ibranch/rbranch. С предсказателем необходимо хотя бы раз выполнить код, чтобы предсказатель понял что после инструкции J надо подавать адрес label на конвейер.

J: ibranch label
...
L: label: ops...

    A F0 F1  S  D  B
 0  J  
 1  L  J              << если предсказатель уже знает про ibranch
 2     L  J           
 3        L  J        
 4           L  J     
 5              L  J  
 6                 L  << инструкция из label
numas13
()
Последнее исправление: numas13 (всего исправлений: 1)
Ответ на: комментарий от numas13

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

То есть, если в среднем на один ibranch более 5 nop или ibranch в цикле, то он может выполняться за один такт.

monk ★★★★★
()
Ответ на: комментарий от monk

Если ты про очередь между frontend и backend (между стадиями B и R), то да это сгладит простои в frontend когда предсказатель не сбрасывал конвейер и до этого было достаточно простоев в backend (nop, mem, etc).

numas13
()
Ответ на: комментарий от numas13

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

А если прикрутят тот предсказатель, то и для условных переходов.

monk ★★★★★
()
Ответ на: комментарий от numas13

Нет. Подразумеваю те, в которые приходится складывать множество nop из-за арифметики и вызовов виртуальных методов.

DAM как раз ускорить не получится, так как это реально условный переход и переход по блокировке всегда считается редким. Для него хорошо бы какую-нибудь прагму прикрутить, чтобы можно было локально отключать, а не через -fno-dam.

monk ★★★★★
()
Ответ на: комментарий от monk

Нет. Подразумеваю те, в которые приходится складывать множество nop из-за арифметики …

Сейчас, без предсказателя, это почти ничем не отличается от подготовленных переходов. Мне кажется, что ты слишком сильно переоцениваешь пользу. Без предсказателя любое ветвление будет обнулять фору для frontend’а и будут нужны задержки backend’a.

{
  nop 4                   << фора
  disp %ctpr1, label
  cmpesb %r0, 0, %pred0
}
{
  ct %ctpr1 ? %pred0      << или
  ibranch label ? %pred0  << без предсказателя ожидаение
}
resume:
{
  ...
}

label:
  ops, no nops
{
  ibranch resume << нужны nops, или проще сделать disp=>ct
                 << с предсказателем такой проблемы не будет
                 << после первого исполнения
}

… и вызовов виртуальных методов

Как это должно помочь с косвенными вызовами?

{
  nop 4
  ldd ..., %r0
} 
{
  nop 7
  movtd %r0, %ctpr1  << E0 E1 E2 WB => A F0 F1 S
} 
  nop                << D
{ 
  call %ctpr1, wbs=N << B
} 

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

Это как повезёт, желательно собрать профиль чтобы исключить DAM в этом случае.

Для него хорошо бы какую-нибудь прагму прикрутить, чтобы можно было локально отключать, а не через -fno-dam.

__attribute__ ((no_dam))

numas13
()
Ответ на: комментарий от numas13

Сейчас, без предсказателя, это почти ничем не отличается от подготовленных переходов.

Сейчас безусловный ibranch label ждёт несколько тактов. Про условный я написал, что нужно прикручивать предсказатель (который разработан).

Как это должно помочь с косвенными вызовами?

На nop 7 конвейер разбора уйдёт на 7 операций вперёд. И после возврата из метода в очереди будут уже разобранные операции (если тело метода маленькое или если делать несколько очередей).

monk ★★★★★
()
Ответ на: комментарий от monk

Сейчас безусловный ibranch label ждёт несколько тактов. Про условный я написал, что нужно прикручивать предсказатель (который разработан).

Ну не суть важно. Главное что у нас с тобой есть понимание, что Эльбрусам нужен предсказатель. Остальное на совести МЦСТ.

На nop 7 конвейер разбора уйдёт на 7 операций вперёд. И после возврата из метода в очереди будут уже разобранные операции (если тело метода маленькое или если делать несколько очередей).

Для косвенного вызова нужно знать адрес. Он будет после завершения movtd. Без предсказателя это будет сложно ускорить.

numas13
()
Ответ на: комментарий от numas13

Он будет после завершения movtd. Без предсказателя это будет сложно ускорить.

Это естественно.

Я про ibranch после этих операций:

{
  nop 4
  ldd ..., %r0
} 
{
  nop 7
  movtd %r0, %ctpr1  << E0 E1 E2 WB => A F0 F1 S
} 
  nop                << D
{ 
  call %ctpr1, wbs=N << B
}
{
  ibranch label
}

Главное что у нас с тобой есть понимание, что Эльбрусам нужен предсказатель. Остальное на совести МЦСТ.

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

monk ★★★★★
()
Ответ на: комментарий от numas13

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

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

uin ★★★
()
Ответ на: комментарий от monk

Я про ibranch после этих операций

Ты точно уверен что это должно работать именно так?

L: {
  nop 4                                                                                 
  ldd ..., %r0       << F
}
M: {
  nop 7 
  movtd %r0, %ctpr1
}  
N: nop
C: { 
  call %ctpr1, wbs=N
}
I: {
  ibranch label
}

    A F0 F1  S  D  B  R E0 E1 E2 E3 E4 ...
 0  L                                     
 1  M  L                                  
 2  N  M  L                               
 3  C  N  M  L                            
 4  I  C  N  M  L                         
 5     I  C  N  M  L                   << queue push L
 6        I  C  N  M  L                << queue push M, pop L
 7           I  C  N  M  L             << queue push N, pop M
 8              I  C  M     L          << structural hazard, ctpr1 not ready
 9              I  C  M        L       
10              I  C  M           L    
11              I  C  M              L 
12              I  C  N  M             << queue pop N
13              I  C  N     M          
14              I  C  N        M       
15              I  C  N           M    << write to ctpr1
16  F           I  C  N              M << ctpr1 fetch start
17     F        I  C  N                
18        F     I  C  N                
19           F  I  C  N                
20              F  C     N             << ctpr1 ready, queue push C, switch to ctpr1
21                 F  C     N          << queue push F, pop C
22                    F  C     N       << queue pop F
23                       F  C     N       
24                          F  C     N    
25                             F  C       
26                                F  C    
27                                   F    

Конечно это только пример с очередью. На реальном Эльбрусе nop не на R, а на B стадии. К тому же там такой себе scoreboarding, каждые 4 такта до 16С и каждые 2 такта после.

numas13
()
Ответ на: комментарий от numas13

Ты точно уверен что это должно работать именно так?

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

То есть в колонке A где-то после 13 такта (появление I в D + 5 тактов) должны быть операции чтения после метки label.

monk ★★★★★
()
Ответ на: комментарий от monk

То есть в колонке A где-то после 13 такта (появление I в D + 5 тактов) должны быть операции чтения после метки label.

Будут до call. После call там уже будет F и другие инструкции за ним, а от ibranch не останется и следа. Я отобразил всё на одной временной линии, т.к. не важно что там после call.

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

I: ibranch label
Y: ...

func:
F: return %ctpr3; nop 5
R: ct %ctpr3
X: ...

ctpr0
    A F0 F1  S  D  B  R
 0  F
 1  R  F
 2  X  R  F             
 3  X  X  R  F          
 4  X  X  X  R  F       
 5  X  X  X  X  R  F    
 6  X  X  X  X  X  R  F << structural hazard (ctpr3), write to ctpr3
 7  X  X  X  X  X  R    << ctpr3 fetch start
 8  X  X  X  X  X  R    
 9  X  X  X  X  X  R    
10  X  X  X  X  X  R    
11  X  X  X  X  X  R    << ctpr3 ready, switch to ctpr3
12  Y  Y  Y  Y  Y  I  R 
13  Y  Y  Y  Y  Y  Y  I 

ctpr3
    A F0 F1  S  D  B  R 
 7  I                   << ctpr3 fetch start
 8  Y  I                
 9  Y  Y  I             
10  Y  Y  Y  I          
11  Y  Y  Y  Y  I       << ctpr3 ready, switch to ctpr3

Я не говорю, что не будет пользы от очереди между стадиями B и R, это зависит от ситуации. На мой взгляд, предсказатель надёжнее в большинстве случаев. Но как средство борьбы с неизвестными безусловными перехода это подойдёт, но не всегда. disp_always будет точнее, т.к. не зависит от backend’a, но у него другие проблемы.

numas13
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.