[Перевод] 5,5 миллиметра за 1,25 наносекунды

В 2004 году я работал в группе Xbox компании Microsoft, в то время она создавала новую консоль. Я получил подробные описания процессора Xbox 360, прочитал их полностью множество раз и внезапно узнал достаточно, чтобы стать официальным специалистом по ЦП. Поэтому я регулярно стал посещать совещания с проектировщиками оборудования, совместно с IBM работавшими над ЦП, и это дало мне ещё больше знаний о процессоре. Именно благодаря этому я обнаружил ошибку проектирования в одной из его команд [перевод на Хабре] и смог помогать разработчикам игр в укрощении этого привередливого зверя.

2754ff29efe7a240c84263fd49b308b6.jpg


Это было очень интересно, и моя работа ценилась, поэтому за несколько месяцев до выпуска консоли я получил подарок от руководства проекта — целую кремниевую пластину процессоров Xbox 360! Этот 30-сантиметровый диск кристаллов ЦП с тех пор постоянно висит в моём домашнем офисе. По своей максимальной площади он содержал 23 полных ЦП по горизонтали и 20 по вертикали, но из-за круглой формы пластины суммарно там было гораздо меньше, чем 460 ЦП. Из-за этого многие процессоры были частично или полностью исключены — я насчитал на пластине 356 полных ЦП.

Пластина выглядит круто, она создаёт красивые радужные дифракционные узоры, а отдельные чипы достаточно велики, чтобы можно было рассмотреть основные элементы ЦП, над которыми я работал в течение пяти лет.

db2514f6edfa0c06b465c4138d0e3c55.jpg


Процессор Xbox 360 имел три ядра PowerPC с кэшем L2 на 1 МБ, и эти элементы чётко видны на пластине.

На показанном выше изображении кристалла (который имеет приблизительный размер 14×12 мм) в правом нижнем углу виден повторяющийся паттерн из небольших чёрных прямоугольников — это кэш L2. Слева от него находится одно из ядер ЦП. Выше, но перевёрнутое вертикально находится ещё одно ядро ЦП, а справа от него и перевёрнутое по горизонтали расположено третье ядро. Когда-то я помнил все видимые элементы ядер (кэши L1? файлы регистров? арифметические блоки?), но уже давно забыл их. Однако они всё равно достаточно хорошо различимы.

image-loader.svg


Кроме трёх ядер ЦП и кэша L2 тут присутствует горизонтальная полоса, идущая посередине чипа, и ещё немного пространства справа от верхнего правого ядра. Думаю, горизонтальная полоса — это шина, соединяющая ядра друг с другом и кэшем L2, а штука в правом верхнем углу — предположительно внекристалльный ввод-вывод.

Изображение с пометками выше — это фотография висящей на стене пластины, сделанная на телефон. Возможно, я предвзят (или травмирован работой с этим своевольным ЦП), но мне кажется, возможность увидеть все элементы чипа совершенно чудесна.

Всё это конечно очень здорово, и вы наверняка хотели бы повесить себе на стену что-нибудь подобное, но история на этом ещё не закончилась. В те времена я писал много бенчмарков, чтобы найти места, в которых производительность ЦП не соответствует ожидаемой нами. Как-то я создал бенчмарк для нашей специализированной процедуры memcpy и обнаружил, что команды выборки с упреждением, отсутствующие в TLB (Translation Lookaside Buffer, также известном как кэш таблицы страниц), отклонялись. Так как обычно мы заранее выполняли выборку с упреждением примерно 1 КиБ (восемь строк кэша по 128 байт), это означало, что при копировании больших объёмов памяти (когда каждая страница на 4 КиБ даёт один промах TLB) приблизительно 25% выборок с упреждением будет отклонено. Эти считывания строк кэша затем обрабатывались последовательно, вместо того, чтобы все восемь обрабатывались параллельно, из-за чего копирование большого объёма памяти занимало почти в три раза больше времени. Эти отклонённые выборки с упреждением были особенно плохи потому, что ЦП Xbox 360 был процессором с исполнением по порядку, поэтому во время ожидания считываний без упреждающей выборки он не мог выполнять никакой другой работы. Это заставило меня переписать кучу, чтобы она использовала страницы на 64 КиБ, что позволяло избежать большинства промахов TLB и восстановить ожидаемую производительность.

4bd49b1da0530542c3517487bdbd5933.jpg


Автопортрет, сделанный в отражении пластины

Итак, я писал множество бенчмарков.

Один написанный мной бенчмарк измерял задержку кэша L2. Это выполнялось следующим образом: создавался список указателей, код проходил по указателям и смотрел, сколько тактов нужно для обхода длинного списка. Имея неизменное оборудование, легко можно создать список указателей, который будет находиться в L1, или всегда будет требовать захода в L2, или всегда требовать захода в основную память. Стандартная система.

Не помню, какой была задержка кэша L2, но помню, что она менялась в зависимости от ядра ЦП, на которой я её тестировал. Задержка L2 из ядра ЦП 0 была с достаточно высокой точностью на четыре такта меньше, чем задержка L2 из ядра ЦП 1 или 2. Любопытно.

CPU die with L2-cache to core arrows shown


Кристалл ЦП со стрелками от кэша L2 к ядрам

Как говорилось выше, вся связь между ядрами ЦП и кэшем L2 выполнялась через эту горизонтальную полосу посередине чипа. Это означает, что весь трафик L2 исходил из верхней части кэша L2, а затем добирался до трёх разных ЦП. Я увеличил предыдущую фотографию кристалла и добавил стрелки, показывающие поток информации от кэша L2 к трём ядрам ЦП. Критично здесь то, что путь к правому верхнему ЦП довольно короткий, а путь к двум ЦП слева заметно длиннее — сигналы должны переместиться по горизонтали через полосу.

Горизонтальные чёрные линии с левого края — это миллиметровые риски на линейке, которую я приложил к пластине, делая фотографию. Я повернул это фото линейки и использовал его для измерения длины горизонтальной красной линии, выяснив, что она составляет 5,5 мм. Так как ЦП Xbox 360 работает с частотой 3,2 ГГц, а ядра ЦП 1 и 2 имеют лишние четыре такта задержки L2, можно подсчитать, что для распространения сигналов на это расстояние в 5,5 мм требуется 1,25 наносекунды!

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

Одна из причин попросту заключается в том, что электрические сигналы в проводах, особенно в очень тонких проводах, не движутся со скоростью света. Ещё одна причина заключается в том, что сигнал не движется непрерывно. Сигнал перемещается на короткое расстояние, а затем запирается какими-нибудь вентилем, а в следующем такте перемещается чуть дальше, поэтому бедный сигнал никогда не получает шанса разогнаться до полной скорости. В-третьих, Xbox 360 проектировался для работы с более высокой тактовой скоростью, но был выпущен с частотой 3,2 ГГц, потому что иначе мог расплавиться. Ситуация с 5,5 мм за четыре такта, вероятно, стало артефактом тех времён, когда такты проектировались гораздо более короткими.

Тем не менее, 5,5 мм за 1,25 наносекунды — это всё равно около 4400 километров в секунду, то есть не особо медленно. Но больше всего мне просто сильно нравится гиковское ощущение радости от того, что я могу собственными глазами видеть эту задержку в 1,25 наносекунды, висящую на моей стене. Спасибо руководству команды Xbox!

Отступление


Изложенная выше история о том, как я стал специалистом по ЦП Xbox 360, достаточно точна. Мне никогда не поручали стать специалистом по ЦП, просто дали доступ к материалам и я изучал их с достаточно фанатичным упорством. Помню, как лежал на полу своей гостиной, когда из-за снегопада отключили электричество, и читал при свете фонаря, пока не разобрался со всеми хитростями конвейера. Тот же шаблон обучения повторялся с любой областью знаний, которой я занимался: анализ сбоев, числа с плавающей запятой, баги компиляторов, баги ЦП. Для меня он работает.

© Habrahabr.ru