Комментарии 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.
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 (редкостное поделие).
Финансовая составляющая там в том, что контроллер диска, способный адресовать и менеджить 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, чтобы гарантированно стать доступной другим ядрам?
wwvvwvwvvww

Почему у нас нет кешей L5?