Когда блокировали RuTracker, LinkedIn и Telegram – я молчал. Когда начали блокировать Tor – я ворчал. Теперь, когда Google выкатили штраф на 7.2 млрд. рублей – я не могу молчать.
То есть пока роскомнадзор с судами рунет кошмарили вы молчали, а как барину штраф выкатили вы не можете молчать. Ясно. Надо еще сбор средств организовать или хотя бы блокировщик рекламы на ютубе отключить.
Имею в виду что в настоящее время ассемблер является очень узким инструментом решения крайне специализированных задачь. Сейчас что ОС, что компиляторы, что биосы с гипервизорами в сервисных чипах - это программы на языках высокого уровня по большей части абстрагированные от конкретного железа. Если перед разработчиком не стоит задача прямой или особой поддержки конкретного процессора/железа то ему и вникать в его архитектуру не зачем. Времена DOS давно прошли.
Естественно, потому что бранчпредиктор не дает бесплатных переходов. В отличии от доп. конвеера с уже заранее подкаченными инструкциями бранча, у него один пайплайн и ему нужно угадать какими инструкциями из какого бранча в следующем такте его начать забивать вслед за инструкцией условного перехода для которой еще даже аргументы не сосчитались. Потому что если этого не сделать переход будет дорогим на всю длинну стадий конвеера.
Сам по себе это и есть костыль для пайплайновых процессоров дабы удешевить переходы, и ошибки предсказания (штатная ситуация для бранчпредикторов) дорого обходятся, так как в этом случае приходится сбрасывать конвейер.
Однако эльбрусовские классические подготовки как назло стоят там где бранчпредиктор вполне себе хорошо справляются и наоборот, плюс первый стоит дорого по оборудованию и не масштабируется, второй же более менее можно допиливать и расширять, вангую в итоге придут к урезаной версии конвеера подготовки и общему бранчпредиктору. Возможно что уже прешли, все таки дока выше 2016г и его в таком виде так и не имплементировали.
И ничего не сказано про главное - return из функции.
Бранчпредиктору все равно возврат, переход,, вызов, прыжок в начало цыкла или что то еще, он не исполняет инструкции он их выдает конвейеру по заранее предсказанному адресу.
Процессоры без ОоО существовали и работали раньше и существуют и работают до сих пор. Никакой такой фундаментальной необходимости в ОоО нет, это чисто приблуда для повышения однопоточной производительности на сегодня уже исчерпавшая свой потенциал, не только из-за того что производительность уже не растет, но и из за дыр которые оно в итоге имплементирует.
Не надо всем его толкать как панацею, его уже довели до совершенства лидеры рынка, нам их не догнать. Сейчас они еще тонны денег в ресерчь вольют, прикроют свои дыры и пропиарят так что от процессоров без этих затычек будут шарахаться как от прокаженных. Рантайм профилирование и взаимодействие с компилятором в динамике это очень интересное и перспективное направление, для рантайм-языков так точно. Предложить то чего у других нет - вот ключ к успеху, а лепить свою формулу-1 и тащить на гонку с определившимися фаворитами на черт знает каком кругу, даже если допустят, бесперспективно.
Я надеюсь что сейчас вы выступаете в роли Рабиновича, наигрывающего Моцарта. Потому что звучит вышенаписанное как лютая хрень.
Хорошо, приведу цитату:
Архитектура «Эльбрус» предполагает наличие в программном коде команд разной длины, поэтому выдача предсказания для подкачки кода необходима до выполнения его декодирования и определения размеров и типа команд. В архитектуре «Эльбрус» введены два типа операций перехода — подготов- ленные и непосредственные, причем количество непосредственных переходов в коде очень неве- лико, для них весьма редко реализуется условие перехода, т. е. в основном они обречены на промах, в данном случае неизвестен заранее адрес пере- хода. С учетом этих факторов было принято реше- ние при проектировании устройства не рассматри- вать операции непосредственного перехода.
То есть переходы по командам ibranch предсказываться не будут, что логично в виду наличия в системе команд кучу инструкций для вычисления адреса перехода, плюс ошибки предсказания проще проглатываются:
Интересно отметить, что отсутствие неупорядо- ченного исполнения команд и раннее вычисление ус- ловия перехода в микропроцессорах с архитектурой «Эльбрус» позволяют упростить реализацию услов- ной отмены команд — вся деятельность при ошибоч- ном предсказании ограничена устройством управ- ления и кэш-памятью команд, а в исполнительные устройства попадают команды только из правильной ветви перехода.
в Эльбрус 32 они все таки вставят этот блок и уберут эту простоту
Ничего подобного они не собираются городить. Рантайм оптимизациями будет заниматься компилятор, а процессор будет собирать и выдавать ему статистику. Эта фича заявлена уже для Эльбрус-16С
В Эльбрус-32С хотят добавить предсказатель переходов, но не такой предсказатель как у суперскаляров если коротко это будет предсказатель подготовленных переходов и 7 управляющих регистров (сейчас только 3).
Надеюсь что они учтут так же подготовку предсказания вызовов, потому что текущая реализация не позволяет подготовить заранее два-три вызова и поочереди их дергать.
2. кладет их в двойной регистр (младшую часть квадрорегистра), старшую часть заранее заполнил нулями,
3. и наконец делает над квадрорегистром адресное преобразование командой movtd (mov tag data или что то типа этого).
Скорее всего он создает таки локальный указатель на данные, по типу (StructRGB *){0,0,0,} только с числом, используя arr как переменную. Если это так то упало скорей всего из за + index надо попробовать отставить arr = (int*)start и посмотреть будет ли ссылка на число.
А при чтении массива падать будет все равно потому что безопасный режим не разрешает читать неинициализированные данные надо его перед этим или заполнить или использовать memset(arr, 0 sizeof(int) * n)
Читать плачь про слишком строгие правила работы с указателем было забавно, учитывая что в других языках с ними вообще ничего нельзя делать, кроме как получить или передать. Запустите лучше вот такой код, если вам не сложно. Интересно все таки структура указателя, по ассемблеру получается что при складывании он увеличивает поле size, может расположение не такое просто.
Там принципиальная проблема: в защищенном режиме 128-битовый указатель содержит размер выделенного блока, тэги, адресс начала блока и offset.
В коде часто встречается присвоение целому значению указателя, потом какая-то арифметика над этим целочисленным значением, а потом присвоение нового значения обратно в указатель.
Причина не в 128и битных указателях. В ассемблере адрес все равно ложится в виде числа на регистр, обращение к памяти происходит специальными командами, в том числе поддерживающими обращение по смещению. А вот сохранить на стек в виде указателя то что не является указателем уже нельзя, банально потому что указатель в безопасном режиме - это тип, а у типов строгие правила преобразования в (зависимости от языка).
В данном примере указатель складывается с целым, что по правилам Си дает указатель. Но вообще оказалось что работает и в первом случае, если расставить явные преобразования типов https://ce.mentality.rip/z/PcrYGM
К слову указатель на процедуру отличается, полагаю и работа с ним тоже. В любом случае весь вот этот безопасный режим это просто как аппаратная виртуальная машина для Си привносящая в него безопасность уровня джавы. И это не такой режим как в интеле при переключении 32/64 адресации, он работает как отдельное адресное пространство работа с которыми происходит через специальные команды. Функции из него наверное даже можно из небезопасного режима вызывать с некоторыми ограничениями, надо только в ОС реализовать поддержку.
Основной конвеер на девять (или больше) стадий, но в дополнение к нему есть еще 3 обрубка на 6 стадий. Обрубка в том смысле что в них код не исполняется никак, а лишь заполняется кодом функции или бранча на 6 (широких) команд и останавливается. Подготовка конвеера запускается командой
disp, %ctpr1, malloc
после чего в любом удобном месте процедуры можно вызвать
call %ctpr1
нижние стадии основного конвеера перецепляются к pipe1 после чего он становится основным, а предыдущий отрезается от исполнения и таким образом ждет возврата. Аргументы передаются путем наложения окна вызываемой процедуры на крайние регистры текущей, может это чуть менее эффективно чем наслоение процедур в интеле, но зато с точки зрения безопасности не подкопаешься.
если цикл хотя бы 50 инструкций, то «следующая итерация» начнётся на +50 от текущей инструкции
Ну даже так может оказаться полезно вынести загрузку данных первой итерации из цикла, а в теле цикла разместить обработку этих данных вместе с загрузкой данных для следующей, как бы "открутив" от него.
Компания Google сообщила о внедрении патчей KPTI и retpoline для блокирования атак Meltdown и Spectre на своих Linux-серверах, в том числе обслуживающих поисковую систему, Gmail, YouTube и Google Cloud Platform. Несмотря на то, что теоретически данные патчи приводят к возникновению дополнительных накладных расходов при выполнении системных вызовов, влияние на производительность обоих патчей при реальной нагрузке Google при выполнении большинства задач оценивается как незначительное. Напомним, что в синтетических тестах наблюдалось проседание производительности до 30% и даже до 60%.
В то же самое время есть пример эльбруса в котором malloc можно подгрузить в дополнительный конвеер сильно заранее и вызвать за один такт когда понадобиться. Может это немного и не то по скорости, все таки пока не переключишься, никакие загрузки оттуда вперед не запустятся, но уж всяко быстрей заплаток безопасности и в статике прекрасно планируется. Хотя реализация на эльбрусе не позволяет например два вызова подготовить и поочередно их запустить, можно только подготовить один, вызвать и только после этого можно начать готовить второй.
Про раскрутку я говорил что "в коде или компиляторе" не во время исполнения естественно.
Спекулятивное/внеочередное исполнение не обладает возможностями ментального вызова функций с неизвестными аргументами для выделения памяти и мгновенным обращением к свежесозданному объекту в следующей итерации
Но оно может заранее попытаться подгрузить node->left, node->right, node->body прямо до проверки node->kind , от типа которого в том числе может зависеть и есть ли вообще эти поля как таковые. В том числе проделать это сразу для нескольких итераций путем раскрутки цикла в коде или компиляторе.
у VLIW проблема - есть критические цепи, которые не позволяют увеличивать частоту
АМД видимо не знали про критические цепи, поэтому у их видеокарт на VLIW частоты были раза этак в 2-3 выше чем у конкурента. И это же не значит что у нвидиа архитектура не позволяла сделать частоты выше, им теплопакет не позволял и жирный размер субядер (у амд под 500-1k на кристалл влазило, у нвидии сотня, максимум две). Пример АМД показателен еще и тем, что первые поколения этой архитектуры (R2000/3000) не давали впечатляющих результатов мягко говоря, но амд продолжала работать дорабатывать архитектуру, кодогенератор, пока в итоге не оказалось что middle-end радеон на уровне или даже обгоняет топ нвидии, и разрыв этот сохранялся вплоть до перехода на GCN. От влив ушли потому что для GPGPU старые ядра не подходили, создавать новый VLIW писать под него и добавлять поддержку в свободное ПО это конечно весело и увлекательно, но амд живет в условиях рынка который диктует свои правила.
Я же постоянно привожу простой вопрос "на подумать" - почему Мцстшный спарк с первого раза на 28нм 2ГГц,
Ну он во первых относится к поколению Э-8СВ на что как бы намекает контроллер памяти DDR4-2400 и дата выхода 2019г. Ну а в пятых-десятых это гораздо более простой и дохленький процессор уровня какого нибудь Cortex-A53 в китайфонах если не проще, при этом 1600Мгц версия 25Вт, а 2Ггц 35Вт вот и весь секрет. Кстати о кортексах - а какие критические цепи байкалу помешали сделать нормальные частоты "не как у эльбруса"? Сослаться на экономию энергии не выйдет ибо 8ядер и 10Гбит эзернет явно не для планшетов решение. Про обещаный серверный 2Ггц RISC-V на 16нм через пять лет вообще промолчу.
ARM делаются под совершенно другое энергопотребление, раз так в 10 ниже
Они это достигают размером самого ядра, которое даже на крошечном по десктопным меркам кристалле 10% занимает если не меньше. В армах нет сложных технологий отключения кэшей/конвееров как в интелах, и этим они с эльбрусом одинаковые, у них есть рабочие частоты и рабочее напряжение 0.8-1.2V, которое даже на старых 45нм интелах позволяло работать на 1,5-3,0Ггц а на армах и эльбрусах только 800-1500Мгц на более тонких техпроцессах. Мотивация впрочем у них разная, у эльбрусов маленькие бюджеты и сроки, можно сказать чисто чтоб люди на работу ходили, студентов в средах проектирования работать учили, и раз в год-два чем то отчитывались сдавали "изделие" которое положат на полку и дадут задание на новое. У армов же рыночек порешал что дешевые массовые чипы за 10-20 долларов предпочтительнее более проработанных за 40-60 долларов. Вот и всё.
Еще в бородатые времена читал на Tom's Hardware (а может кстати и на хабре, не помню уже) что наращивание частоты упирается в скорость переключения транзисторов, 5Ггц для них предел и IBM работает над созданием новых которые позволят наращивать дальше вплоть до 10Ггц. Но в статье пишут про 7nm Samsung так что врядли это та самая революция которую нам обещали. Ну и конечно же 960Мб L4 и 256Мб L3 впечатляет.
Высокие тактовые частоты достигаются более детальным уровнем проектирования микросхемы (full custom design). Никакие архитектуры здесь вообще непричем. На примере процессоров ARM нетрудно заметить что на тех же 16nm типичные частоты у них ~2Ггц, на 7-5нм уже подобрались к 3Ггц. И эльбрус и доступные на рынке ARM процессоры делаются из стандартных ячеек/блоков фабрики, а так высоких частот не достичь.
Вы уверены, что disp %ctpr1 можно выполнять сразу после операции перехода?
Конечно можно, в чем проблема? Мало тог, оно и выполняется сразу в следующем такте, nop 2 стоит для следующей команды, которая очевидно использует результат ldw,0 %dr10, %dr3, %r0
Это утверждение не соответствует действительности. Писать код долго и дорого. По факту сделать процессор за 500 миллионов дешевле и быстрее
Вы бредите, даже в той же мцст разработкой софта (всего - библиотеки, компиляторы дистрибутив) занимается 20 человек, а железом 200. Во вторых какая бы железка не была, хоть за 100 хоть за 500 миллионов, под нее все равно придется софт портировать и ускорять под новые инструкции, автоматом к процессору ничего не прилогается.
Бабаян там явным образом говорит о несостоятельности VLIW подхода, фразой "Ну мы и решили его попробовать. Ведь мы тогда минусов не знали этой широкой команды…"
Под несостоятельностью "VLIW подхода" он имеет в виду сугубо статичность аппаратуры, это даже не в плане in-order vs out-of-order, а в плане того что как сейчас в эльбрусе все шесть практически универсальных ALC вынуждены вставать на ожиданиях данных или чего то еще дружной командой, синхронно, потому что широкие команды подразумевают такую синхронизацию - вот это он называет под минусом широкой команды.
Но прошу обращаю внимание именно широкую команду он считает плохой а не эльбрус. Вот что он предлагает сейчас: динамические стрендыпо сути те же ALC и каждый стренд в своем кластере с дубликатом регистрового файла (привет эльбрус). Строгое in-order исполнение, никакого бранчпредиктора, код для стрендов готовит компилятор, контекстная безопасность (аkа "Безопасный режим"). Все по сути то же самое, все все что в каком то виде уже было в эльбрусах 1-2-3 - вот тебе развитие, никакого тупика в развитии родных идей Бабаян не видит.
А теперь включи оптимизации как в статье (-O2 или выше), выбери компилятор как в статье (gcc 7.5, а не кланг) и внезапно получишь во-первых ассемблерный листинг как в статье (а не колбасу на 30+ инструкций), а во-вторых - не поверишь, 2-4 такта на итерацию.
Он же ОоО суперскаляр, у него все есть в железе и ему не нужно полагаться на компиляторы как какой нибудь там тупиковый VLIW. Они вон все ненадежные: https://godbolt.org/z/8qe454f4z компиляешь с максимальными оптимизациями -O3 а результат хуже чем с -O2 в два раза - 3.3 такта против 1.75
Гораздо проще и лучше транзисторов еще там сям приляпывать и вообще выкинуть компиляторы как класс на свалку истории. Пользователь только спасибо скажет, раньше одним и тем же процессором приходилось обходится по несколько лет, а теперь скажет с предвкушением откладываю на осенний сезон аппаратных обновлений.
считаю производительность и такты для него с закрытыми глазами
Ты молодец, но ты забываешь что это именно эльбрусовская система команд тебе это позволила сделать. Для интела ты свой навык применять не можешь, ты не видишь микрокод и не знаешь что внутри происходит: https://godbolt.org/z/qaxdEeGo6 10~13 тактов интел тратит, никакие не три. Хватит людям в уши лить.
Кстати, эти три такта, которые он получил тоже будут только в хороших случаях, в общем случае нам понадобится не менее 4 тактов.
Да откуда вы берете эти три такта? Там в цикле 3000 итераций (10000 / 3) замеры выдают 22000 тактов на весь цикл что эквивалентно 7~8 тактов на итерацию.
Конечно это не 17 тактов, но и не один. В 7~8 раз медленней чем могло бы быть при инлайне (причем это самый минимум, так как цикл можно еще развернуть и ускорить в 100+ раз), но зато быстрее эльбруса на заведомо медленном коде в 2.5 раза.
То есть пока роскомнадзор с судами рунет кошмарили вы молчали, а как барину штраф выкатили вы не можете молчать. Ясно. Надо еще сбор средств организовать или хотя бы блокировщик рекламы на ютубе отключить.
Имею в виду что в настоящее время ассемблер является очень узким инструментом решения крайне специализированных задачь. Сейчас что ОС, что компиляторы, что биосы с гипервизорами в сервисных чипах - это программы на языках высокого уровня по большей части абстрагированные от конкретного железа. Если перед разработчиком не стоит задача прямой или особой поддержки конкретного процессора/железа то ему и вникать в его архитектуру не зачем. Времена DOS давно прошли.
Ну такое.
Даже в ссср на первых жигулях половина импортных деталей стояло (и не только на жигулях). Импортозамещалось всю жизнь все поэтапно.
Естественно, потому что бранчпредиктор не дает бесплатных переходов. В отличии от доп. конвеера с уже заранее подкаченными инструкциями бранча, у него один пайплайн и ему нужно угадать какими инструкциями из какого бранча в следующем такте его начать забивать вслед за инструкцией условного перехода для которой еще даже аргументы не сосчитались. Потому что если этого не сделать переход будет дорогим на всю длинну стадий конвеера.
Сам по себе это и есть костыль для пайплайновых процессоров дабы удешевить переходы, и ошибки предсказания (штатная ситуация для бранчпредикторов) дорого обходятся, так как в этом случае приходится сбрасывать конвейер.
Однако эльбрусовские классические подготовки как назло стоят там где бранчпредиктор вполне себе хорошо справляются и наоборот, плюс первый стоит дорого по оборудованию и не масштабируется, второй же более менее можно допиливать и расширять, вангую в итоге придут к урезаной версии конвеера подготовки и общему бранчпредиктору. Возможно что уже прешли, все таки дока выше 2016г и его в таком виде так и не имплементировали.
Бранчпредиктору все равно возврат, переход,, вызов, прыжок в начало цыкла или что то еще, он не исполняет инструкции он их выдает конвейеру по заранее предсказанному адресу.
Процессоры без ОоО существовали и работали раньше и существуют и работают до сих пор. Никакой такой фундаментальной необходимости в ОоО нет, это чисто приблуда для повышения однопоточной производительности на сегодня уже исчерпавшая свой потенциал, не только из-за того что производительность уже не растет, но и из за дыр которые оно в итоге имплементирует.
Не надо всем его толкать как панацею, его уже довели до совершенства лидеры рынка, нам их не догнать. Сейчас они еще тонны денег в ресерчь вольют, прикроют свои дыры и пропиарят так что от процессоров без этих затычек будут шарахаться как от прокаженных. Рантайм профилирование и взаимодействие с компилятором в динамике это очень интересное и перспективное направление, для рантайм-языков так точно. Предложить то чего у других нет - вот ключ к успеху, а лепить свою формулу-1 и тащить на гонку с определившимися фаворитами на черт знает каком кругу, даже если допустят, бесперспективно.
Хорошо, приведу цитату:
Архитектура «Эльбрус» предполагает наличиев программном коде команд разной длины, поэтому
выдача предсказания для подкачки кода необходима
до выполнения его декодирования и определения
размеров и типа команд. В архитектуре «Эльбрус»
введены два типа операций перехода — подготов-
ленные и непосредственные, причем количество
непосредственных переходов в коде очень неве-
лико, для них весьма редко реализуется условие
перехода, т. е. в основном они обречены на промах,
в данном случае неизвестен заранее адрес пере-
хода. С учетом этих факторов было принято реше-
ние при проектировании устройства не рассматри-
вать операции непосредственного перехода.
То есть переходы по командам ibranch предсказываться не будут, что логично в виду наличия в системе команд кучу инструкций для вычисления адреса перехода, плюс ошибки предсказания проще проглатываются:
Интересно отметить, что отсутствие неупорядо-ченного исполнения команд и раннее вычисление ус-
ловия перехода в микропроцессорах с архитектурой
«Эльбрус» позволяют упростить реализацию услов-
ной отмены команд — вся деятельность при ошибоч-
ном предсказании ограничена устройством управ-
ления и кэш-памятью команд, а в исполнительные
устройства попадают команды только из правильной
ветви перехода.
Главное чтоб можно было делать:
а не как сейчас. Судя по описанию реализации все для этого есть.
Ничего подобного они не собираются городить. Рантайм оптимизациями будет заниматься компилятор, а процессор будет собирать и выдавать ему статистику. Эта фича заявлена уже для Эльбрус-16С
В Эльбрус-32С хотят добавить предсказатель переходов, но не такой предсказатель как у суперскаляров если коротко это будет предсказатель подготовленных переходов и 7 управляющих регистров (сейчас только 3).
Надеюсь что они учтут так же подготовку предсказания вызовов, потому что текущая реализация не позволяет подготовить заранее два-три вызова и поочереди их дергать.
Я ничего не фантазирую а смотрю в ассемблер и на сообщения компилятора.
И он скомпилировал это без каких либо предупреждений, при этом в ассемблере хорошо видно что:
1. он загружает данные размером 32бита
2. кладет их в двойной регистр (младшую часть квадрорегистра), старшую часть заранее заполнил нулями,
3. и наконец делает над квадрорегистром адресное преобразование командой movtd (mov tag data или что то типа этого).
Скорее всего он создает таки локальный указатель на данные, по типу
(StructRGB *){0,0,0,}только с числом, используяarrкак переменную. Если это так то упало скорей всего из за+ indexнадо попробовать отставитьarr = (int*)startи посмотреть будет ли ссылка на число.А при чтении массива падать будет все равно потому что безопасный режим не разрешает читать неинициализированные данные надо его перед этим или заполнить или использовать memset(arr, 0 sizeof(int) * n)
Читать плачь про слишком строгие правила работы с указателем было забавно, учитывая что в других языках с ними вообще ничего нельзя делать, кроме как получить или передать. Запустите лучше вот такой код, если вам не сложно. Интересно все таки структура указателя, по ассемблеру получается что при складывании он увеличивает поле size, может расположение не такое просто.
Если речь про что то типа такого:
То это скорее всего работать не будет, но будет работать вот так:
Причина не в 128и битных указателях. В ассемблере адрес все равно ложится в виде числа на регистр, обращение к памяти происходит специальными командами, в том числе поддерживающими обращение по смещению. А вот сохранить на стек в виде указателя то что не является указателем уже нельзя, банально потому что указатель в безопасном режиме - это тип, а у типов строгие правила преобразования в (зависимости от языка).
В данном примере указатель складывается с целым, что по правилам Си дает указатель. Но вообще оказалось что работает и в первом случае, если расставить явные преобразования типов https://ce.mentality.rip/z/PcrYGM
К слову указатель на процедуру отличается, полагаю и работа с ним тоже. В любом случае весь вот этот безопасный режим это просто как аппаратная виртуальная машина для Си привносящая в него безопасность уровня джавы. И это не такой режим как в интеле при переключении 32/64 адресации, он работает как отдельное адресное пространство работа с которыми происходит через специальные команды. Функции из него наверное даже можно из небезопасного режима вызывать с некоторыми ограничениями, надо только в ОС реализовать поддержку.
Нет, не в кэши, а в конвеер. Устроено это примерно вот так:
Основной конвеер на девять (или больше) стадий, но в дополнение к нему есть еще 3 обрубка на 6 стадий. Обрубка в том смысле что в них код не исполняется никак, а лишь заполняется кодом функции или бранча на 6 (широких) команд и останавливается. Подготовка конвеера запускается командой
disp, %ctpr1, mallocпосле чего в любом удобном месте процедуры можно вызвать
call %ctpr1нижние стадии основного конвеера перецепляются к pipe1 после чего он становится основным, а предыдущий отрезается от исполнения и таким образом ждет возврата. Аргументы передаются путем наложения окна вызываемой процедуры на крайние регистры текущей, может это чуть менее эффективно чем наслоение процедур в интеле, но зато с точки зрения безопасности не подкопаешься.
Ну даже так может оказаться полезно вынести загрузку данных первой итерации из цикла, а в теле цикла разместить обработку этих данных вместе с загрузкой данных для следующей, как бы "открутив" от него.
А может и не начать
В то же самое время есть пример эльбруса в котором malloc можно подгрузить в дополнительный конвеер сильно заранее и вызвать за один такт когда понадобиться. Может это немного и не то по скорости, все таки пока не переключишься, никакие загрузки оттуда вперед не запустятся, но уж всяко быстрей заплаток безопасности и в статике прекрасно планируется. Хотя реализация на эльбрусе не позволяет например два вызова подготовить и поочередно их запустить, можно только подготовить один, вызвать и только после этого можно начать готовить второй.
Про раскрутку я говорил что "в коде или компиляторе" не во время исполнения естественно.
Спекулятивное/внеочередное исполнение не обладает возможностями ментального вызова функций с неизвестными аргументами для выделения памяти и мгновенным обращением к свежесозданному объекту в следующей итерации
Но оно может заранее попытаться подгрузить
node->left, node->right, node->bodyпрямо до проверкиnode->kind, от типа которого в том числе может зависеть и есть ли вообще эти поля как таковые. В том числе проделать это сразу для нескольких итераций путем раскрутки цикла в коде или компиляторе.АМД видимо не знали про критические цепи, поэтому у их видеокарт на VLIW частоты были раза этак в 2-3 выше чем у конкурента. И это же не значит что у нвидиа архитектура не позволяла сделать частоты выше, им теплопакет не позволял и жирный размер субядер (у амд под 500-1k на кристалл влазило, у нвидии сотня, максимум две). Пример АМД показателен еще и тем, что первые поколения этой архитектуры (R2000/3000) не давали впечатляющих результатов мягко говоря, но амд продолжала работать дорабатывать архитектуру, кодогенератор, пока в итоге не оказалось что middle-end радеон на уровне или даже обгоняет топ нвидии, и разрыв этот сохранялся вплоть до перехода на GCN. От влив ушли потому что для GPGPU старые ядра не подходили, создавать новый VLIW писать под него и добавлять поддержку в свободное ПО это конечно весело и увлекательно, но амд живет в условиях рынка который диктует свои правила.
Ну он во первых относится к поколению Э-8СВ на что как бы намекает контроллер памяти DDR4-2400 и дата выхода 2019г. Ну а в пятых-десятых это гораздо более простой и дохленький процессор уровня какого нибудь Cortex-A53 в китайфонах если не проще, при этом 1600Мгц версия 25Вт, а 2Ггц 35Вт вот и весь секрет. Кстати о кортексах - а какие критические цепи байкалу помешали сделать нормальные частоты "не как у эльбруса"? Сослаться на экономию энергии не выйдет ибо 8ядер и 10Гбит эзернет явно не для планшетов решение. Про обещаный серверный 2Ггц RISC-V на 16нм через пять лет вообще промолчу.
Они это достигают размером самого ядра, которое даже на крошечном по десктопным меркам кристалле 10% занимает если не меньше. В армах нет сложных технологий отключения кэшей/конвееров как в интелах, и этим они с эльбрусом одинаковые, у них есть рабочие частоты и рабочее напряжение 0.8-1.2V, которое даже на старых 45нм интелах позволяло работать на 1,5-3,0Ггц а на армах и эльбрусах только 800-1500Мгц на более тонких техпроцессах. Мотивация впрочем у них разная, у эльбрусов маленькие бюджеты и сроки, можно сказать чисто чтоб люди на работу ходили, студентов в средах проектирования работать учили, и раз в год-два чем то отчитывались сдавали "изделие" которое положат на полку и дадут задание на новое. У армов же рыночек порешал что дешевые массовые чипы за 10-20 долларов предпочтительнее более проработанных за 40-60 долларов. Вот и всё.
Еще в бородатые времена читал на Tom's Hardware (а может кстати и на хабре, не помню уже) что наращивание частоты упирается в скорость переключения транзисторов, 5Ггц для них предел и IBM работает над созданием новых которые позволят наращивать дальше вплоть до 10Ггц.
Но в статье пишут про 7nm Samsung так что врядли это та самая революция которую нам обещали. Ну и конечно же 960Мб L4 и 256Мб L3 впечатляет.
Высокие тактовые частоты достигаются более детальным уровнем проектирования микросхемы (full custom design). Никакие архитектуры здесь вообще непричем. На примере процессоров ARM нетрудно заметить что на тех же 16nm типичные частоты у них ~2Ггц, на 7-5нм уже подобрались к 3Ггц. И эльбрус и доступные на рынке ARM процессоры делаются из стандартных ячеек/блоков фабрики, а так высоких частот не достичь.
Конечно можно, в чем проблема? Мало тог, оно и выполняется сразу в следующем такте, nop 2 стоит для следующей команды, которая очевидно использует результат
ldw,0 %dr10, %dr3, %r0Вы бредите, даже в той же мцст разработкой софта (всего - библиотеки, компиляторы дистрибутив) занимается 20 человек, а железом 200. Во вторых какая бы железка не была, хоть за 100 хоть за 500 миллионов, под нее все равно придется софт портировать и ускорять под новые инструкции, автоматом к процессору ничего не прилогается.
Под несостоятельностью "VLIW подхода" он имеет в виду сугубо статичность аппаратуры, это даже не в плане in-order vs out-of-order, а в плане того что как сейчас в эльбрусе все шесть практически универсальных ALC вынуждены вставать на ожиданиях данных или чего то еще дружной командой, синхронно, потому что широкие команды подразумевают такую синхронизацию - вот это он называет под минусом широкой команды.
Но прошу обращаю внимание именно широкую команду он считает плохой а не эльбрус. Вот что он предлагает сейчас: динамические стрендыпо сути те же ALC и каждый стренд в своем кластере с дубликатом регистрового файла (привет эльбрус). Строгое in-order исполнение, никакого бранчпредиктора, код для стрендов готовит компилятор, контекстная безопасность (аkа "Безопасный режим"). Все по сути то же самое, все все что в каком то виде уже было в эльбрусах 1-2-3 - вот тебе развитие, никакого тупика в развитии родных идей Бабаян не видит.
Он же ОоО суперскаляр, у него все есть в железе и ему не нужно полагаться на компиляторы как какой нибудь там тупиковый VLIW. Они вон все ненадежные: https://godbolt.org/z/8qe454f4z компиляешь с максимальными оптимизациями -O3 а результат хуже чем с -O2 в два раза - 3.3 такта против 1.75
Гораздо проще и лучше транзисторов еще там сям приляпывать и вообще выкинуть компиляторы как класс на свалку истории. Пользователь только спасибо скажет, раньше одним и тем же процессором приходилось обходится по несколько лет, а теперь скажет с предвкушением откладываю на осенний сезон аппаратных обновлений.
Ты молодец, но ты забываешь что это именно эльбрусовская система команд тебе это позволила сделать. Для интела ты свой навык применять не можешь, ты не видишь микрокод и не знаешь что внутри происходит: https://godbolt.org/z/qaxdEeGo6 10~13 тактов интел тратит, никакие не три. Хватит людям в уши лить.
Да откуда вы берете эти три такта? Там в цикле 3000 итераций (10000 / 3) замеры выдают 22000 тактов на весь цикл что эквивалентно 7~8 тактов на итерацию.
Конечно это не 17 тактов, но и не один. В 7~8 раз медленней чем могло бы быть при инлайне (причем это самый минимум, так как цикл можно еще развернуть и ускорить в 100+ раз), но зато быстрее эльбруса на заведомо медленном коде в 2.5 раза.