LINUX.ORG.RU
ФорумTalks

Предсказатель переходов на Эльбрусе (v7)

 ,


1

3

Появились материалы доклада на форуме Встраиваемые системы реального времени 2024. (Было видео докладчика из МЦСТ, но утонуло в грубинах Telegram, найти не могу).

https://files.kpda.ru/upload/iblock/310/f2tgak1k9clukvwr0peykst9oh01vcyj.pdf

Так вот, смотрим 13-ю страницу. В 7-й версии архитектуры появился предсказатель переходов. Но как-то он вяленько добавляет производительности (около ~5%). Вопрос - почему?

Мои варианты:

1. На нативном коде предсказатель переходов много не прибавит, потому что и без него все оптимизировано, и FDO/PGO (Profile Guided Optimizations) дает свои плоды.

2. Этот предсказатель впихнули чтобы разогнать интерпретируемые/jit языки, а на нативном коде от него будет толку немного.

3. Это первая итерация предсказателя, странно было бы ожидать хороших результатов. Главное, что эффект от присутствия предсказателя на лицо, в следующих итерациях его надо развивать.

Ваши варианты.

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

установненный на опыте факт

Ну да, 5%. Такое себе.

я не говорил о рандомных данных

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

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Я не понимаю что вы пытаетесь доказать. Что Itanium/Эльбрус лучше x86_64 с его спекулятивным исполнением и предсказанием переходов? А почему тогда Intel в итоге забросила Itanium несмотря на огромныа вложенные средства и перешла на x86_64 от AMD? Не смогли правильный компилятор написать? А в МЦСТ смогли?

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

с его спекулятивным исполнением и предсказанием переходов

С каким «его»? Спекулятивное выполнение на Эльбрусе было отродясь, это вообще-то суть подхода. Предсказатель запилили. Вопрос казалось бы закрыт. Но нет, всё равно прутся какие-то чебурашки и кукарекают про «радикально» лучше.

А в МЦСТ смогли?

А у тебя жопа от этого сгорела? В интеле много чего не смогли.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Я правильно понимаю, что предсказатель перехода немного выправит ситуацию на интерпретируемых/JIT языках, но прирост производительности будет в лучшем случае 20-22% (судя по тесту perlbmk)?

В то время как надо ускорять ~x3 раза чтобы достигнуть сопоставимой с Intel скорости (в пересчете на мегагерц).

И это ускорение x3 появится только тогда, когда для Эльбруса появятся соответствующие JIT-компиляторы, использующие нативные коды Эльбруса? И это надо сделать для всех языков программирования, каковые имеют JIT под Intel для адекватного паритета.

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

надо ускорять ~x3 раза чтобы достигнуть сопоставимой с Intel скорости (в пересчете на мегагерц).

Теоретическая скорость на такт и так вроде бы в порядке. Сколько там последние интелы могут двойной точности операций на такт молотить? 32 осилили, или 16 до сих пор?

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)

Какая-то это хня, улучшение в архитектуре процессоров которые никто не увидит.
Думаю что бы не случилось всегда можно будет себе достать какой-нибудь минипк с intel n100 (или его аналоги) и он уделает любой эльбрус. Ну а если человек Z-патриот и хочет служить на военку то ему лучше изучать embedded и FPGA.

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

Ты забыл рассказать про nop-ы для подготовленных переходов. :)

// elbrus-v6
{
    ldd,0 [ func_ptr ], %g16
    nop 4 // ждём результат ldd
}
{
    movtd,0 %g16, %ctpr1 // подготавливаем переход
    nop 7
}
    nop // выжидаем 9 тактов на подготовку перехода
    call %ctpr1, wbs=4
{
    return %ctpr3 // подготавливаем возврат
    nop 5 // выжидаем 6 тактов на возврат
}
{
    addd,0 %b[0], 0, %r0
    ct %ctpr3
}
// elbrus-v7
{
    ldd,0 [ func_ptr ], %g16
    nop 4
}
    icalld %g16, wbs=4
{
    addd,0 %b[0], 0, %r0
    iret
}
numas13
()
Ответ на: комментарий от Xintrea

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

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

В то время как надо ускорять ~x3 раза чтобы достигнуть сопоставимой с Intel скорости (в пересчете на мегагерц).

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

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

32 операции с AVX-512 в серверных Xeon (9 лет как?). Сейчас вот и в Zen 5 так же. У Эльбрусов пока что только 24 в идеальном случае (без обращений в память на запись).

// теор. макс.
512 (AVX-512) / 64 * 2 (FMA) * 2 (FPU) = 32
128 (v5) / 64 * 2 (COMB/v5, FMA/v6) * 6 (ALC) = 24

Примерно в 6 раз медленнее на ядро с Zen 5, но это с разными тактовыми частотами.

--------------------------------------------------------------
| Instruction Set | Core Computation      | Peak Performance |
| AVX512F         | FMA(f64,f64,f64)      | 1.3483 TFLOPS    |
| elbrus-v5       | ADD(MUL(f64,f64),f64) | 229.72 GFLOPS    |
--------------------------------------------------------------

https://github.com/pigirons/cpufp/blob/master/benchmark_result/x64.md

https://github.com/pigirons/cpufp/blob/master/benchmark_result/e2k.md

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

Какой то у тебя странный код, почему movtd надо выжидать 8 тактов? В конвеере же всего 6 стадий. Зачем инструкции с call $ctpr1 один nop? И разве можно сложение одновременно с возвратом делать? Обычно компилятор не ставит в команды с переходами ничего, наверное неспроста.

А все увидел у тебя ноп и вызов без скобок, с телефона трудно мешанину разобрать

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

В ителе вручную делается префетч, свертка цикла с упихиванием чисел в 512 вектора, и луп-анрол на 4-8 итераций вперед что бы забить конвеер побольше.
Иначе побайтовая обработка и тормоза.

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

Какой то у тебя странный код, почему movtd надо выжидать 8 тактов? В конвеере же всего 6 стадий.

6 стадий только до B/базирование, прибавляй его и ещё 2 стадии (R/чтение и E0/исполнение), т.к. адрес приходит после E0. Вот и получается 9 тактов.

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

Можно. Почему компилятор так не делает? Потому, что возврат долго подготавливать…

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

Так сама инструкция перехода тоже декодируется/исполняется вот тебе и набираются такты

{nop 7; movtd} ~ 8 тактов сама инструкция 1 + 7 задержка в ней
{call} - 9й такт, но по идее запускать можно на 8й так как на стадии запуска уже гарантированно пройдет 9ть и в этом как бы и был смысл этих нопов железка инфантильно доводит даже неготовые операнды до талого и только если они на стадии исполнения неготовы она встает на цикличном ожидании. И то это в старых версиях, в v6 сделали что он ровно ждет до готовности, иначе весь старый код где лоад из L1 4такта превратился в 8тактов ожидания.

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

но по идее запускать можно на 8й…

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

в v6 сделали что он ровно ждет до готовности

В v6 уменьшили штрафы за неправильно учтённые задержки. Eсли раньше штраф был 0-3 такта (синхронизация каждые 4 такта), то в v6 штраф 0-1 такта (каждые 2 такта). В данном случае будет либо 9 тактов (без штрафа), либо 10 тактов (+1 такт). Зависит от времени запуска исходной инструкции.

иначе весь старый код где лоад из L1 4такта превратился в 8тактов ожидания.

Будет либо 5 тактов (задержка load в v6), либо 6 тактов (+1 штраф). До v6 было бы от 4 до 7 тактов.

Когда сделают на каждом такте то надобность в nop-ах полностью отпадёт, но пока это не так.

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

Вот так получается, значит тогда вовсе 11~12 тактов стоит подготовка вызова из адресной переменной.

typedef int (*_call)(int);

int add(int v) {
   static int d = 0;
   d++;
   return v + d;
}

int mul(int v) {
   static int m = 1;
   m++;
   return v * m;
}

int sub(int v) {
   static int s = 0;
   s++;
   return v - s;
}

_call functs[3] = {&add,&mul,&sub};

int main (int argc, const char *argv[]) {
    int i = functs[argc](argc),
        j = functs[argc+1](argc+1);
    //printf('test %i %i\n', i, j);
    return 0;
}

/*
{
  nop 2
  ldd,0	%dr1, [ _f64,_lts0 $functs ], %dr1
}
{
  nop 7
  movtd,0	%dr1, %ctpr1
}
{
  nop 1
}
{
  call	%ctpr1, wbs = 0x9
}
{
  nop 2
  ldd,0	%dr1, [ _f64,_lts0 $functs ], %dr1
}
{
  nop 7
  movtd,0	%dr1, %ctpr1
}
{
  nop 1
}
{
  call	%ctpr1, wbs = 0x9
}*/

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

Да. В условном интерпретаторе байткода OoOE будет исполнять всё в спекулятивном режиме (чтение опкода, чтение jump table, вычисление операции) ещё до вычисления адреса перехода (при условии что предсказатель не ошибся даже несколько операций параллельно), а Эльбрус вынужден ждать даже с предсказателем переходов (разве что предсказанная ветка обработается в начальных стадиях конвейера до подтверждения точности предсказания). Что уже намного лучше чем с подготовленными переходами.

Поэтому дальнейший рост производительности в таких задачах для Эльбруса – это сокращение отставания в тактовой частоте от других процессоров и полирование того что есть. ИМХО.

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

Сомневаюсь что интел забивает себе контекст хрен пойми каким кодом. Вообще в эльбрусе-2 было такое же, называлось «совмещением процедур» и в эльбрусе-3 вот этими подготовками как раз пытались реализовать то что было в нем, только программно аппаратно - подгрузка пролога и не более.

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

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

У Эльбрусов пока что только 24 в идеальном случае

В идеальном 48. Правда условия идеальности не очень понятны.

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

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 4)
Ответ на: комментарий от no-such-file

это максимальное количество операций в ШК, он имеет в виду чисто вычислительные. Хотя лично мне интересней как раз максимальное количество полноценных команд вместо дутых гигафлопсов засчет векторов, сегодня из за видеокарт это все менее актуально, по крайней мере в индустрии. Десктопы/серверы последний оплот.

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

Сомневаюсь что интел забивает себе контекст хрен пойми каким кодом.

Увы, но так работают процессоры с OoOE. :)

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

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

Вчера голова уже не соображала, сам не понял что написал.

Конечно же он грузит код, в идеале после декодирования джампа/вызова предсказатель сразу должен начинать грузить ее инструкции, иначе буду пропуски в конвеере, и чем длинней конвеер тем будет больнее.
Длинный конвеер позволяет интелу не имея кучи устройств молотить не хуже влив (а то и лучше), но интел далеко не сразу научился работать с длинной овер 30+ стадий, все помним факап с пентиум 4, просто так его влупить эффект будет отрицательный.

В любом случае предсказание это не SMT а всего лишь диспетчер оберегающий конвеер от простоев. Плюс в этом вопросе интелу/амд помогает фронтенд, если твой OoOE на каком нибудь рискфайв будет без фронтенда то он будет в точно такой же (если не в худшей) ситуации как предсказатель на эльбрусе. Как минимум если попытаешься сделаешь длинный конвеер как на интеле возникнет ситуация при которой условия для переходов будут неуспевать посчитаться. В общем то на арме даже и не пытаются и частоты поднимают засчет повышения тока путем уменьшения площади электросхемы с сохранением рабочего напряжения (как на эльбрусе). А эпл взяла и вхреначила фронтенд, правда из за того что бакенд (конвеер, устройства) ванильный армовский, частот там нет, но зато потребляет немного, эплу норм.

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

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

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

Вчера голова уже не соображала, сам не понял что написал.

Утром тоже не особо соображает. ;)

numas13
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)