LINUX.ORG.RU
ФорумTalks

Расскажите про современный Hyper-threading

 ,


1

3

На момент появления, технология Hyper-threading решала вопрос неполной загрузки супер-сверх-длинного конвеера ЦП. Да, речь про времена интел прескот. И это было понятно.

Сейчас у интеля очень эффективное ядро с лучшей однопоточной производительностью. И почему-то есть гипертрейдинг. А что оно, собственно, делает в современных ЦП?

★★★★★

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

Откуда инфа о том, кто там как делит кэши в M1?

Из головы.
На самом деле это просто логично, как еще ядро A57 получит быстро контекст от А53? Через память, да еще медленную-мобильную шину данных это будет просто ....LITTLE без big, а так хоть теперь понятно в чем идея общий кэш с мелкоядрами. Ну и кстати насчет Apple m1 не совсем понятно реально ли он там shared для всех или вот так же только для своих компаньонов.

Я тебя умоляю, удвоить кэш — это серьезная архитектурная задача?

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

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

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

Академически чистый RISC как и VLIW никому не нужен, если там нет нужного набора комманд и код выполняется медленнее

«Академически чистый RISC» в свое время обоссал x86, когда DEC Alpha вычислял в разы быстрее интеля, и интелю понадобились годы для сокращения разрыва, но в конце-концов DEC Alpha был выкуплен интелем, MIPS пал жертвой неадекватного менеджмента, в живых остались только SPARC и ARM. Интель в свое время даже создал собственные RISC платформы, но потом передумал.

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

Я чот не понял, а с фронтом не нужно их восстанавливать со стэка? Может быть и да, но я первый раз про такое слышу. Это уже не говоря о том, что в «академически чистых RISC» использовалось большое число регистров, которые заметно снижали потребность в сохранении/восстановлении.

И то же самое примерно с риск командами - для того что бы декодировать fp16

Даже с расширениями SIMD и вещественными числами там нужно постараться, чтобы выйти в 1000+. У армов образца 90-х годов даже без SIMD получалось выходить за тысячу. У AArch64 без векторов и плавающих точек порядка 200 инструкций, но отдельные инструкции сложные (вроде LDM/STM) — это на самом деле это даже более RISC, чем вообще всё, что до этого делал ARM (по-хорошему AArch64 имеет мало общего со старыми инструкциями ARM, это полный редизайн).

Переименование - чек
Толстый набор инструкций - чек

Речь не о большом числе, а о большой сложности инструкций. В старых ARM почти все инструкции имели высокую сложность (несколько операций в одной инструкции). Как результат — комбинаций инструкций в старом арм порядка двух тысяч, в x86 — много тысяч, может быть десятки тысяч, в типовых RISC 90-х — порядка сотни, у AArch64 базовых — примерно 300 штук:
https://developer.arm.com/documentation/ddi0597/2022-03/Base-Instructions
К слову, от переменной длины отказались.

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

Dec alpha разве был risc?
Как бы там нибыло x86 в то время был чистым циском и не претендавал на что то серьезное. Кроме того у интела был и риск процессор - i960 и был так же стековый i465 (это типа как виртуальный на джавамашине, только аппаратный).
Фирма dec же с лохматых времен славилась монстроузными поделиями, которые где то там на бумаге рыали всех на деле никто не знает, потому что их мало кто в живую видел. Зато видели мипс и спарк с powerpc и да они выглядели неплохо, даже майкрософт в NT4 поддерживала все перечисленные, потому что не верила в вечность x86.

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

В архитектуре х86 16 регистров, но внутри, в микроархитектуре их 128, фронтенд декодируя входной код переназначает регистры с посути виртуальных на физические, в процессе декодирования попался условный джамп или вызов, бранчпредиктор посмотрел в историю пришел к выводу что скорее всего будет переход начал загружать код вызываемой функции, регистры ее переменных так же переназначаются на свободные физические. Один из аргументов функции указывает ссылкой на переменную в стеке, суперскаляр увидев что адрес тянется к переменной вызывающей процедуры, находит тот же регистр, ставит операции из функции к нему в зависимость.
И вот так процедура за процедурой поступают через фронтенд в мясорубку пока регистровый файл не закончится, и только когда закончиться часть откачается в стек что бы освободить поляну.

Речь не о большом числе, а о большой сложности инструкций. В старых ARM почти все инструкции имели высокую сложность (несколько операций в одной инструкции)

Ну может, оно и было циск, там же родословная из 80х годов, когда были популярны моторолы 68к и 8086.

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

Dec alpha разве был risc?

Да: https://www.cs.tufts.edu/~nr/toolkit/specs/alpha.html

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

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

Далее, вот здесь

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

Я совсем не понял, что ты хотел сказать. Я в курсе про Stack Engine и переименование доступа к стэку в доступ к регистру, но как оно связано с твоей фразой — понятия не имею.

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

Так. И что мне с этого?

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

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

Вот, теперь я могу ответить на эту фразу вне очереди, когда зависящая операция закончилась.

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

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

Прежде всего, это поведение x86, на ARM такое не нужно, потому что там есть буфер записи

Буфер записи чего и куда? Если процедура пишет в стек, то надо писать в память/стек так как значение может быть видно еще откуда то.
При процедурном переходе, текущее состояние регистров надо откачивать в стек, потом при возврате возвращать, мало того их надо еще очищать для безопасности. При переименовании регистров этого всего не требуется, так как регистры вызывающей процедуры и регистры вызванной находятся по соседству в одном регистровом файле, непересекаемость гарантирована железом.
В микроархитектуре Cortex A78 что-то около трехсот регистров + несколько десятков векторно-вещественных, для чего по твоему они еще могут быть кроме как не для хранения контекстов процедур? В системе команд арма не доступно столько регистров одновременно.

Есть только один альтернативный способ делать примерно то же самое и без фронтенда - это регистровое окно SPARC. Там тоже большой регистровый файл, но процедуре доступно только 32, когда происходит процедурный переход, окно едет вперед на чистое место, а при возврате едет назад и таким образом старая процедура (например с циклом который вызывает функцию) никуда со всеми ее переменными не девается, и все работает довольно шустро. Вызов конечно все равно дорогой, но возврат - бесплатный.
Я не помню как в спарке аргументы функций передаются, вроде через спецрегистры окна типа i1 o1, которые как то там накладываются, но это в данном ращговоре не важно важно что все выравнено все по класике, все в духе RISC.
Ну и кстати, SIMD не является ни частью риск ни частью циск, это векторное расширение системы команд, так что все таки справедливее из 1000+ комманд отделять векторный набор от основного. Интел и арм к слову так и делают - aarch может быть с neon и thumb, а может быть и без.
x86 может быть с sse и avx, а может быть и без. Сколько тогда комманд получается, ты считал ли?

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

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

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

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

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

Прежде всего, это поведение x86, на ARM такое не нужно, потому что там есть буфер записи

Буфер записи чего и куда?

Я погуглил — в A78 уже отказались от этой модели:
https://en.wikichip.org/wiki/arm_holdings/microarchitectures/cortex-a78

From the L1, the A78 supported up to 20 outstanding non-prefetch misses. Previously, the A77 had an 85-entry load buffer and a 90-entry store buffer. Arm says the functionality of those two buffers is now distributed across several structures. Hercules improved the data prefetchers. Arm says Hercules introduced a number of new prefetch engines, covering some new stride patterns and new irregular access patterns

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

Если процедура пишет в стек, то надо писать в память/стек так как значение может быть видно еще откуда то

При переименовании регистров этого всего не требуется

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

У меня есть устойчивое впечатление, что ты путаешь x86 и ARM. Хотя, даже там stack engine не отменяет записей в память, он нужен лишь для оптимизации ублюдочного сишного стиля передачи аргументов через стэк и частые push/pop, использующие лишние uop-ы на inc/dec esp/rsp (stack engine устраняет только операции над esp/rsp, всё остальное сохраняется) — от такой работы со стэком даже на x86-64 уже отошли, где аргументы передаются регистрами и функция заранее имеет гарантированное место в стэке. Вот, смотри:
https://godbolt.org/z/f8j39exjr
16 аргументов, 8 из них передаются через стэк, остальные регистрами. В самой функции при исчерпании регистров не начинает использоваться стэк, как в x86, а вытесняются старое содержимое регистров w19-w29 в стэк и новые данные размещаются в них.

В микроархитектуре Cortex A78 что-то около трехсот регистров + несколько десятков векторно-вещественных, для чего по твоему они еще могут быть кроме как не для хранения контекстов процедур?

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

Какое отношение к нашему разговору про кэши они имеют? Да никакого. О чем я и писал. Кэши инструкций расположены рядом с декодером-бранчпредиктором и кэши данных расположены рядом с очередями store-load только для того, чтобы сократить задержку. И в том числе по этой причине кэш данных и кэш инструкций расположены в разных местах. A78 «из коробки» разработан под опциональные размеры кэша 32 или 64 кб, я не вижу причин для того, чтобы дальнейшее удвоение этого размера на что-то влияло.

x86 может быть с sse и avx, а может быть и без. Сколько тогда комманд получается, ты считал ли?

У x86 очень тяжело посчитать число команд, если считать команды с разными типами аргументов разными командами. В руководстве по AArch64 разная длина аргумента описывается как отдельная команда, если что, и при таком подсчете их получается три сотни. Наличие условных переходов в инструкции умножает число операций на число этих условий — именно потому у старого ARM на самом деле очень сложный набор инструкций, даже посложнее x86 будет, ведь в x86 не пытались в каждую инструкцию засунуть условное выполнение и битовый сдвиг в дополнение к основной операции.

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

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

Часто на логических схемах кэш инструкций рисуют вне фронтенда:
https://www.mirabilisdesign.com/doc_files/doc/CodeDoc/WebHelp/VisualSimDocs/l...
С точки зрения оптимизации производительности удобно его разместить как можно ближе к узлам, обращающимся к этому самому кэшу. В остальном для них это просто абстрактный кэш, выдающий данные порциями по 64 байт.

Расширяешь их что бы больше инструкций захватывать, расширяешь все - декодер, реордер буфер, весь фронтенд

При чем тут Re-Order Buffer к фронту? ROB-у еще более безразлично устройство всех кэшей.

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

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

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

Потому меня не покидает мысль о том, что Apple нарастил кэш и пайплайны ПРОСТО РАДИ ЦИФЕРОК. Забавно, что мы почти ничего не знаем про устройство M1, но знаем размер его L1 кэша и ширину пайплайна. Да, может быть на синтетике увеличенный кэш дает рост, но в типовой современной программе твой L1 рано или поздно кончится, причем, кэш-мисс может случиться при любом размере кэша — по этой причине ни AMD, ни Intel не пытаются сделать L1 больше 64 кб в сумме, ведь это просто бессмысленно.

Заметь, что медиатеки-квалкомы на кортексах отличаются по однопоточной производительности от A14/M1 буквально на 20%:
https://www.cpubenchmark.net/CPU_mega_page.html

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

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

Пайплайн это уже порты исполнения, в современных интелах пайплайн гораздо длиннее чем был у пеньтиума 4. Что то околого 30 стадий, тогда как у пня4 было 24 что-ли. От того и частоты под 5 ггц.

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

У меня к слову есть prescot 2004г там уже поддерживается sse3 и x86-64 и даже гипертрейдинг (правда почему то в линуксе отключен, как я понял из интернетов он на п4 кривой и вызывает краши), но никаких P-states (отключение части конвеера и снижение как следствие рабочей частоты) у него ещё нет, это просто селерон на стеройдах разогнанный до 3ггц и требующий кулер на 96вт желательно. При этом производительность примерно как у 65нм кор 2 дуо 2ггц, если тому отключить ядро. Надо бы кстати проверить на каких нибудь бенчмарках, так как есть и то и то.

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

Пайплайн это уже порты исполнения, в современных интелах пайплайн гораздо длиннее чем был у пеньтиума 4. Что то околого 30 стадий, тогда как у пня4 было 24 что-ли. От того и частоты под 5 ггц

У x86 сложнее система команд плюс строгая модель памяти, это накладывает свой отпечаток НА ДЛИНУ, но не на ширину пайплайна и очередь внеочередного выполнения. У современных AMD/Intel ширина стадий decode-issue порядка 4-6, у M1 — 8. Ты действительно веришь в то, что оно реально что-то дает? Всё, что оно дает — это быстро построенную огромную очередь операций, которые ждут завершения друг друга, и полный отсос в случае ошибки предсказания ветки на плохо кэшированных функциях. Мне почему-то вспомнился Need For Speed, где была специфичная категория машин, которые могли на прямой дистанции разогнаться до бешенных скоростей, но очень плохо управлялись на поворотах. Вот это M1.

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

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

У интела так не получается из за разных декодеров на разные типы инструкции.

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

У яблока длинна конвеера судя по тому что частоты не сильно отличаются от собратьев по архитектуре на том же техпроцессе, не менялась особо

Какая разница, какая у тебя длина-ширина конвеера, если загруженные в нее команды не будут выполняться? Загрузить 630!! операций в очередь так, чтобы они потом успешно выполнились, желательно не строго по очереди — это нужно очень постараться. Любой неугаданный бранч, любой динамический переход — и досвидания. Я в 160 так-то не особо верю, это сильно избыточное количество, созданное лишь для упрощения реализации.

И что то похожее вроде было в нвидиа денвер кажется.

У Denver-а ПОочередное выполнение, VLIW, 2 декодера, 7 линий исполнения, 13 шагов пайплайна.

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

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

У меня были серверы на alpha, рвали как тузик грелку интелы в числодробильнях. Ну и стоит вспомнить, что «Титаник» считали на альфах.

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

Закапывали-закапывали, только закопали, и вот опять.

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