Comments 34
то мы буквально имеем в виду, что электрический сигнал проходит по металлическому проводнику длиной в несколько миллиметров или сантиметров. И это тоже расстояние, пусть и ничтожное по человеческим меркам, но при тактовой частоте 3–4 ГГц оно уже имеет значение, просто потому что за один такт электрон в идеальных условиях будет проходить всего 10 сантиметров, а в металлическом проводнике на кристалле и того меньше.
Строго говоря - неправильно. Для медного проводника сечением 1мм2 и токе 1А скорость направленного движения электронов 0.073 мм/сек. Понятно, что на самом деле имелась ввиду скорость распространения электромагнитного поля.
Благодарю, поправил на сигнал, так будет корректнее.
@dalerank скажите, вы написали две как я понимаю фундаментальные причины, препятствующие созданию кэша L5 - это физическое ограничение скорости света (сигнал просто не успевает дойти) и сложности с когерентностью данных между ядрами (протоколы типа MESI). А как вы считаете, какой из этих факторов станет непреодолимым барьером раньше при попытке масштабирования кэш-памяти? И возможно ли, что развитие 3D-компоновки чипов или переход к новым протоколам когерентности (например, с директориями вместо широковещательного снупинга) сможет сдвинуть этот барьер в обозримом будущем?
"путь электрона" остался в следующем абзаце.
И тогда же компиляторы (в первую очередь Borland C++) начали применять такое понятие как локальность данных, оптимизируя размещение переменных и порядок объявлений в структурах и стараясь уложить горячие поля рядом
Это бьёт по ABI ведь... Сейчас в плюсах такое запрещено, а объявление структуры однозначно задаёт оффсеты полей.
Ну дядя Борман был известным приколистом в этом плане, на его багах я застал -Og, когда внутри функции делалась подфункция если некоторые части были одинаковые. И я бы никогда не знал про эту дичь если бы не странные краши, которые она порождала. Или -Ov, который пытался выносить переменные и инваринты из циклов. Или "фантастический" -Ob режим, который умел склеивать функции под капотом, что тоже добавляло отладки в ночи.
Суть не в том, что компилятор меняет порядок полей (он этого не делает), а в том что программисты начали сами группировать горячие поля в начале структуры, чтобы влезать в 64 байта
У IBM вроде бы есть ~динамический L2/L3 cache.
Также интересно, как себя проявляет в разных реальных задачах Xeon Max
(академический интерес в обоих случаях ))
Хеоны у меня были в руках очень давно, но в числомолотилках, да еще под ICC скомпиленых они уделывали AMD и обычные гражданские версии не то, что на проценты - в разы в некоторых случаях, на GCC результаты были сильно скромнее. Но, это было в 2008.
IBM в своих мейнфреймах серии z исторически использовала нестандартные иерархии памяти с бо́льшим числом уровней, чем принято в x86-мире
К слову, IBM давно экспериментирует с нестандартными иерархиями памяти. Любопытный пример - IBM 2361 (конец 1960-х, архитектура System/360). Это блок расширения ОП, который адресуется так же, как и "основная" ОП, но медленнее неё (8 мкс вместо 750 нс на Model 65).
Говоря о времени распространения сигнала можно вспомнить борьбу Seymour Cray за компактность процессора его суперкомпьютеров.
И это тоже расстояние, пусть и ничтожное по человеческим меркам, но при тактовой частоте 3–4 ГГц оно уже имеет значение
Да, как-то задумался, что при тактовой частоте 3ГГц за один такт луч света успевает преодолеть 10 см.
Размышления:
До всех кризисов память стоила копейки, казалось бы почему не воткнуть 64 gb в жесткий диск в кэша, но даже серверные решения даже близко не имели такого кэша. Почему, причина не техническая,а финансовая.
По теме статьи мнение:
С кэшем процессора, далеко не все решения имеют техническую составляющую, очень часто решение имеет даже не экономическую, а маркетинговую составляющую.
Были SSHD, но беглая гуглежка показывает, что больше их никто не выпускает, значит что-то пошло не так.
Строго говоря, флеш-память в современных жестких дисках, всё же, встречается
Пристально следил за прогрессом SSHD в свое время. Тесты показывали, что выигрыш был заметен далеко не на всех задачах, а стоили гибриды ощутимо дороже обычных HDD. Потребители проголосовали кошельком - в пользу «чистых» SSD, которые как раз переживали маленькую революцию с контроллерами SandForce.
есть такое, у знакомых на билдферме стоит пара Samsung PM9AX c 16гб кеша, но скажу что кардинально они картину не меняют, снижение времени сборки билда не стоит этих денег. Сам диск стоит как самолет и потом оказалось что дешевле было докупить 128Гб оперативки и развернуть в ней временный диск.
Так это SSD 7Тб/с, там другие ограничения будут в реальной жизни. Я же говорил про то, что берем тормознутый HDD, добавляем большой кэш, для определенных применений получаем решение - горячие данные всегда в кэше, а холодные на HDD. Сейчас время этого решения наверное уже ушло, но лет 15 оно вполне было себе актуально при нормальной реализации, а не как в свое время делали SSHD (редкостное поделие).
Финансовая составляющая там в том, что контроллер диска, способный адресовать и менеджить 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, чтобы гарантированно стать доступной другим ядрам?
Нет, барьеры не выталкивают данные в L2, как вы выразились. smp_wmb() просто инструкция упорядочивания, которая гарантирует что все записи до барьера станут видны другим ядрам раньше записей после барьера. Это понятие только об относительном порядке видимости, и физические если вы откроете годболт там будет чтото вроде mfence или lock xchg, и все отложенные записи из store-буфера коммитятся в L1D конкретного ядра, а вот полетят ли они дальше в L2 вопрос. Ядро просто пометит свою копию как Invalid. Более того, L1D ядра1 может вообше отдать линию напрямую ядру2 через HITM, минуя L2, и изменения там появятся только когда ядро3 придет за этими данными, но там тоже есть особенности работы на старых Intel/Amd до 15года
Если взять весь кэш современного CPU, что-то около 2Мб
Вы один нолик, как минимум, потеряли
Большое спасибо автору - видно, что человек глубоко разбирается и сильно напрягался, чтобы сделать текст более доступным.
Мне когда-то умные люди объясняли эту идею через ту же метафору «шкаф-ящик-коробка», но немного с другой стороны. Суть в балансе скорости, цены и физики. Регистры процессора - это «коробка» прямо в руках: мгновенный доступ, но если попытаться сделать ее объемом побольше, то критически увеличится размер кристалла, упадет выход годных, и все это будет стоить непомерно дорого. Оперативка - «шкаф»: вместительный и дешевый, но медленно и далеко. Разница в скорости между ними всегда измерялась в порядках. Сейчас: 2-3 порядка.
Огромный разрыв в скорости регистров и RAM делает эффективной схему с несколькими промежуточными уровнями хранения: за разные деньги и с разной скоростью. Поэтому между ними - кэши («ящики»): дешевле регистровой памяти такого же объема, но дороже RAM, а по скорости, также между ними. Количество уровней определяется техпроцессом и здравым смыслом. Каждый следующий слой добавляет стоимость, задержку и усложняет управление всей системой, а прирост производительности в какой-то момент перестает окупать стоимость этих ящиков.
Цель всей конструкции - выжать максимальное быстродействие для целевых задач за приемлемые деньги.
И да, все аналогии ложны.
Почему у нас нет кешей L5?