Обновить

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

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

Строго говоря - неправильно. Для медного проводника сечением 1мм2 и токе 1А скорость направленного движения электронов 0.073 мм/сек. Понятно, что на самом деле имелась ввиду скорость распространения электромагнитного поля.

Благодарю, поправил на сигнал, так будет корректнее.

"путь электрона" остался в следующем абзаце.

И тогда же компиляторы (в первую очередь Borland C++) начали применять такое понятие как локальность данных, оптимизируя размещение переменных и порядок объявлений в структурах и стараясь уложить горячие поля рядом

Это бьёт по ABI ведь... Сейчас в плюсах такое запрещено, а объявление структуры однозначно задаёт оффсеты полей.

Ну дядя Борман был известным приколистом в этом плане, на его багах я застал -Og, когда внутри функции делалась подфункция если некоторые части были одинаковые. И я бы никогда не знал про эту дичь если бы не странные краши, которые она порождала. Или -Ov, который пытался выносить переменные и инваринты из циклов. Или "фантастический" -Ob режим, который умел склеивать функции под капотом, что тоже добавляло отладки в ночи.

Суть не в том, что компилятор меняет порядок полей (он этого не делает), а в том что программисты начали сами группировать горячие поля в начале структуры, чтобы влезать в 64 байта

У IBM вроде бы есть ~динамический L2/L3 cache.

Также интересно, как себя проявляет в разных реальных задачах Xeon Max

(академический интерес в обоих случаях ))

Хеоны у меня были в руках очень давно, но в числомолотилках, да еще под ICC скомпиленых они уделывали AMD и обычные гражданские версии не то, что на проценты - в разы в некоторых случаях, на GCC результаты были сильно скромнее. Но, это было в 2008.

4 stacks of HBM2e, 64 gigabytes of ultra-high-bandwidth in-package memory and over 1GB of HBM capacity per core...

...ought to be enough for anybody?)

И не только в 2008. В 2025 так же. Что торч, что сьютспарс, что всякие оптимизаторы юзающие мкл, работает на них сильно быстрее.

IBM в своих мейнфреймах серии z исторически использовала нестандартные иерархии памяти с бо́льшим числом уровней, чем принято в x86-мире

К слову, IBM давно экспериментирует с нестандартными иерархиями памяти. Любопытный пример - IBM 2361 (конец 1960-х, архитектура System/360). Это блок расширения ОП, который адресуется так же, как и "основная" ОП, но медленнее неё (8 мкс вместо 750 нс на Model 65).

Говоря о времени распространения сигнала можно вспомнить борьбу Seymour Cray за компактность процессора его суперкомпьютеров.

И это тоже расстояние, пусть и ничтожное по человеческим меркам, но при тактовой частоте 3–4 ГГц оно уже имеет значение

Да, как-то задумался, что при тактовой частоте 3ГГц за один такт луч света успевает преодолеть 10 см.

Размышления:

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

По теме статьи мнение:

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

Были SSHD, но беглая гуглежка показывает, что больше их никто не выпускает, значит что-то пошло не так.

Строго говоря, флеш-память в современных жестких дисках, всё же, встречается

есть такое, у знакомых на билдферме стоит пара Samsung PM9AX c 16гб кеша, но скажу что кардинально они картину не меняют, снижение времени сборки билда не стоит этих денег. Сам диск стоит как самолет и потом оказалось что дешевле было докупить 128Гб оперативки и развернуть в ней временный диск.

Так это SSD 7Тб/с, там другие ограничения будут в реальной жизни. Я же говорил про то, что берем тормознутый HDD, добавляем большой кэш, для определенных применений получаем решение - горячие данные всегда в кэше, а холодные на HDD. Сейчас время этого решения наверное уже ушло, но лет 15 оно вполне было себе актуально при нормальной реализации, а не как в свое время делали SSHD (редкостное поделие).

Fusion Drive от эппл передаёт привет. Там ровно эта идея реализована имеющимися на тот момент аппаратными средствами - ссд на 32-64 ГБ плюс хдд на 500 ГБ в рамках одного раздела. Горячие данные на ссд, холодные на хдд...

Финансовая составляющая там в том, что контроллер диска, способный адресовать и менеджить 64Гб кэша с нормальным алгоритмом вытеснения, стоил бы как сам сервер)

почему не воткнуть 64 gb в жесткий диск

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

Про MESI протокол упомянули вскользь, а ведь именно накладные расходы на когерентность снупинга убивают масштабирование кэшей больше чем на 8-16 ядер

Это не было темой статьи. Я вам больше скажу, обычный (широковещательный) snooping MESI нормально работает только на 2-4 ядрах. Если интересно больше технических деталей то можно вот это почитать (https://habr.com/ru/articles/689310/), на 6–8 накладные расходы уже соизмеримы и превышают время работы с переменной в L2. Но все зависит от паттерна работы, если вся работа в пределах одного ядра то проблем не будет, проблема начинается там, где есть write-sharing, когда несколько ядер пишут в одни и те же или соседние кэш-линии. Но даже на двух ядрах можно подложить себе граблей с false sharing, если два потока пишут в разные переменные, которые случайно лежат в одной кэш-линии. И тогда с точки зрения MESI они делят одну линию, и каждая запись одного ядра инвалидирует кэш другого, хотя логически данные вообще независимы. Это классическая грабля при написании многопотока, еслиatomic counter1 и stomic counter2 лежат рядом в структуре, то они почти гарантированно окажутся в одной кешлинии и будут постоянно пинговать друг друга между ядрами, но увидите и почините вы это очень не скоро, если увидите вообще.

У ЦП reorder buffer 300+ микроинструкций, задержка на чтение RAM около 60нс, на 5ГГц это 300 тактов. Так что в идеальном случае память прочитается даже без кэшей.

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

Не понял как кэш L1D может не требовать согласования с другими ядрами. Вот есть разделяемая переменная x и один поток, выполняемый на ядре 1, будет в нее писать, а другой - на ядре 2 из нее читать. Потоку 1 повезло и x попала в L1D. Я знаком с понятием store-буфера и что записи не обязательно должны вообще сразу попасть в кэш, если у нас нет write-барьера, но в какую именно кэш?

x=1;
smp_wmb();

Значит ли это, что после барьера x будет вытолкнута в L2, чтобы гарантированно стать доступной другим ядрам?

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

Публикации