Текст книги "Журнал «Компьютерра» №37"
Автор книги: Компьютерра Журнал
сообщить о нарушении
Текущая страница: 5 (всего у книги 11 страниц) [доступный отрывок для чтения: 5 страниц]
Если теперь вернуться к технологическому описанию конвейера, то изложенный выше процесс с конвертами происходит следующим образом. Из очереди в 24 линии по три mOP’а в каждой ICU выбирает в наиболее удобной для исполнения последовательности один-три mOP’а и пересылает их либо на ALU, либо на FPU – в зависимости от типа микрооперации. В случае ALU микрооперации сразу же попадают в очередь планировщика (шесть элементов по три mOP’а), который подготавливает необходимые для исполнения микрооперации ресурсы, дожидается их готовности и только потом отправляет mOP вместе со всеми необходимыми данными на исполнение. Причем при исполнении одного mOP’а на самом деле может происходить исполнение сразу двух действий – несложных арифметических вычислений, которые часто возникают при обращении к оперативной памяти (ими занимается блок Address Generation Unit, AGU), и «сложных», требующих вмешательства «полновесного» ALU, – соответствующая «двойка» микроинструкций (ROP) закладывается в mOP еще на стадии декодирования. Подготовка данных в планировщике занимает (в идеальном случае) один такт, исполнение – от одного (подавляющее большинство инструкций) до трех (при обращении к оперативной памяти) и даже пяти (64-битное умножение) тактов.
С блоком FPU все чуточку сложнее. Для начала вышедшие из ICU mOP’ы проходят две стадии по подготовке их операндов. Затем – накапливаются в планировщике FPU (двенадцать элементов по три mOP’а), который, по аналогии со своим целочисленным собратом, дожидается, пока данные для этих mOP’ов будут готовы, а исполнительные устройства освободятся, и разбрасывает накопленные mOP’ы по трем исполнительным устройствам. Но в отличие от целочисленной части конвейера (где содержатся по три одинаковых блока ALU и AGU), исполнительные устройства FPU «специализированы» – каждое производит только свой специфический набор действий над числами с плавающей запятой. Время выполнения: два такта на переименование и отображение регистров, один такт (в идеале) на планирование и ожидание операндов, четыре такта на собственно исполнение.
Финал же у всех закончившихся микроопераций один – они «возвращаются» в ICU с полученными результатами, и ICU, по мере готовности линий, потихоньку производит их отставку. На все про все в идеальных условиях у нас ушло 10-17 тактов, причем за каждый такт мы исполняли по три mOP’а (это обычно 1,5-3 инструкции x86).
Устройство процессоров Intel архитектуры NetBurst
Архитектура NetBurst сегодня лежит в основе всех процессоров Pentium 4, Xeon и Celeron. Эффективная длина конвейера в зависимости от варианта составляет 20 или 31 стадию. Количество одновременно исполняемых инструкций за такт в устоявшемся режиме – до четырех; тактовые частоты серийно выпускаемых процессоров – от 2,53 до 3,8 ГГц – это по всем показателям лучше данных по K8. Лучше, но, к сожалению, только сугубо теоретически и на специально подготовленном коде.
***
NetBurst тщательно оптимизировалась для работы на высоких частотах, и назвать эту архитектуру классической можно только с большой натяжкой. Для начала упомянем хотя бы тот же Trace Cache (TC), заменяющий в NetBurst классический Гарвардский I-cache (L1 code). Идея состоит в том, что в NetBurst декодер вынесен за пределы собственно конвейера – процессор конвертирует x86-инструкции в свое внутреннее представление не на лету, как AMD K8, а заблаговременно, еще на стадии копирования кода в кэш-память первого уровня. Устроено это все так своеобразно (например, в процессе декодирования декодер убирает безусловные переходы, занимается предсказанием условных переходов и может едва ли не «разворачивать» циклы!), что внутреннему устройству Trace Cache и декодеру инструкций для него вообще можно посвятить отдельную статью (чего мы делать сейчас не будем; скажем только, что декодер для TC работает очень медленно). Точная длина соответствующего участка конвейера неизвестна, но составляет, по разным оценкам, от 10-15 до 30 тактов – то есть этот «скрытый» участок конвейера имеет длину едва ли не большую, чем «видимый». Таким образом, введение TC позволяет практически вдвое уменьшить эффективную длину конвейера (страшно даже представить NetBurst без Trace Cache)[С K8, кстати, та же самая история – декодированием и подготовкой инструкций занята примерно половина конвейера. Есть предположения, что в следующем поколении процессоров AMD – архитектуре K9 – появится и Trace Cache. Скажем, в K8 подобное нововведение уменьшило бы видимую длину конвейера до 6-7 стадий в целочисленных вычислениях и до 12 стадий в вычислениях с плавающей точкой!]! Емкость TC для всех NetBurst составляет 12 тысяч микроопераций; в терминах классического x86 это соответствует примерно 8-16 Кбайт кэша L1-data; причем работает TC и обслуживающая его логика на половинной частоте ядра и наполняется декодером с темпом не более одной новой инструкции за такт. Поэтому если процессор некстати вылетит на незакэшированный участок кода (а кэш маленький, и подобная ситуация вполне возможна), то от теоретически возможных четырех инструкций за такт в лучшем случае останется лишь одна. Подобные «резкие потери темпа» вообще свойственны архитектуре NetBurst; к счастью, такие ситуации возникают редко.
Дальнейшее повествование я буду вести, указывая время исполнения инструкции для ядра Northwood (20-стадийный конвейер). Для более нового Prescott в целом справедливо все то же самое, просто время исполнения отдельных стадий слегка возросло.
Первые четыре такта работы конвейера – извлечение специальным блоком выборки инструкций из TC и второй этап предсказания условных переходов. В первый раз декодер TC уже пытался предсказать переход, так что второй этап предсказания фактически сводится к «угадыванию» того, правильно ли декодер угадал переход еще «в тот раз» или нет. Заодно для некоторых записей TC («закладок»["Закладки" позволяют увеличить эффективный объем Trace Cache, поскольку вместо нескольких mОР’ов мы храним в нем одну «закладку»]) происходит их «развертывание» в несколько микроопераций. В силу того что TC работает на половинной частоте ядра, происходит выборка довольно медленно и каждый ее этап занимает по два такта конвейера. Затем полученные микрооперации (до шести штук за такт) складываются в традиционную очередь выборки (Fetch Queue), где буферизуются, сглаживая неравномерность декодирования и обеспечивая «на выходе» устоявшийся темп декодирования в три микроинструкции за такт. Задержка, вносимая буферизацией, – 1 такт; еще 1 такт расходуется на то, чтобы подготовить внутренние ресурсы процессора для выбранной из Fetch Queue тройки mOP’ов. Затем еще два такта уходит на то, чтобы подготовить для каждого mOP’а персональные физические регистры для вычислений (в рамках техники переименования регистров). И, наконец, на последнем, девятом по счету такте полностью готовые к исполнению mOP’ы начинают «распихиваться» по очередям инструкций, стоящих на выполнение.
Зачем понадобилась вся эта каша с многократными очередями? Разработчики NetBurst пытались добиться того, чтобы все стадии конвейера были независимы друг от друга и работали асинхронно, без точной привязки к некой «единой тактовой частоте» процессора. Именно асинхронность (а не только длинный конвейер!) позволяет резко повысить тактовые частоты, на которых способно работать ядро процессора.
Вернемся к конвейеру NetBurst. Итак, подготовленные к исполнению инструкции на девятом такте распределяются по двум очередям – очереди для AGU-инструкций, обращающихся к оперативной памяти (длина – 16 mOР’ов), и очереди для всего остального (32 mOP’а). На следующем такте инструкции из этих очередей разбираются аж пятью независимо работающими планировщиками – планировщиком AGU, двумя «быстрыми» и двумя «медленным» планировщиками. «Быстрые» имеют дело лишь с некоторыми самыми простыми арифметико-логическими операциями и работают на удвоенной тактовой частоте процессора, успевая забирать из очередей по две простые инструкции за такт. Нужны они для того, чтобы загружать работой «быстрые» же исполнительные блоки, построенные на специальной быстродействующей логике и тоже работающие на удвоенной тактовой частоте (до 8 ГГц!), обрабатывая по две инструкции за такт. «Медленные» планировщики «специализируются» каждый на своем типе инструкций и работают на номинальной частоте ядра. Планировщики могут переупорядочивать микрооперации по своему усмотрению (OoO-исполнение); они же отслеживают ход выполнения микроопераций, при необходимости перезапускают их и в конце выполнения инструкции записывает полученные результаты в оперативную память; на все про все у них уходит еще три такта процессора. Наконец, планировщики через четыре порта запуска (порты частично общие, а это значит, что «быстрые» и «медленные» планировщики конкурируют друг с другом за то, кто из них получит право запускать в текущем такте подготовленные mOP’ы дальше) переправляют упорядоченные микрооперации в очереди диспетчеров, где они дожидаются «разрешения на запуск». И тут начинается самое интересное.
Задача диспетчера – подготовить для микрооперации операнды таким образом, чтобы, когда команда прибыла на исполнительное устройство, необходимые для вычисления данные оказались там же. Но конвейер NetBurst устроен так, что диспетчер и собственно исполнительное устройство довольно сильно разнесены по конвейеру, и чтобы данные и микрооперация пришли одновременно, микрооперацию на исполнение требуется запускать задолго до того, как будет получено подтверждение готовности ее операндов. Если быть точным, то после запуска инструкции диспетчером два такта уйдет на подготовку данных, три такта – на исполнение команды и еще один такт – на проверку результатов[В NetBurst, как и в других архитектурах, используется быстрая выборка данных из кэша, когда, грубо говоря, «вначале вытаскиваем данные, а потом уж смотрим, что мы такое вытащили». Выборка происходит при совпадении лишь небольшой части запрошенного и найденного адресов, а проверка на то, что остальная часть адреса тоже совпадает, – производится параллельно с выборкой «вроде как найденных» данных и исполнением операции над ними], после чего инструкции уже можно будет отправлять «в отставку». Стало быть, нужно отправлять инструкцию за пару тактов до того, как данные понадобятся; причем ошиблись мы или нет, станет известно еще позже – тактов эдак через пять-семь, когда диспетчер успеет выпустить соответствующее количество инструкций, часть из которых уже будет выполнена (!). А если мы ошиблись, что тогда делать? Авторы NetBurst предложили весьма своеобразное решение – «реплей».
Снова попробую объяснить ситуацию «на пальцах». Представьте, что конвейер – это рельсовый путь, а по нему бегают вагончики – микрооперации, указывающие, что процессору нужно изготовить и в вагончики погрузить. Причем путей в нашем процессоре несколько, и инструкции разных видов – катятся по разным рельсам. Задача диспетчера, – организовать оптимальным образом движение по своей железнодорожной ветке. Что он делает? Время вагончика в пути от его станции до станции, где вагончик загрузят полезным грузом, ему известно; так что нашему диспетчеру (а всего их семь) остается только связаться с другими диспетчерами и запросить у них информацию о том, когда будут готовы те данные, которые «его» микрооперации используют в качестве исходных, и отправить вагончик с таким расчетом, чтобы он и данные, полученные на другой ветке от другой микрооперации, прибыли на исполнительное устройство одновременно.
Загвоздка в том, что некоторые вагончики имеют обыкновение опаздывать или привозить совсем не то, что запрашивалось, постфактум сообщая о накладке. Соответствующая подобным микрооперациям неспокойная ветка в процессоре отведена для вагончиков, обращающихся к оперативной памяти; причем часто результат выполнения этих микроопераций выступает как исходные данные для другого mОР’а. Поэтому в архитектуре NetBurst порой возникает ситуация, когда микрооперация на исполняющее устройство прибыла, а исходные данные для ее исполнения – нет, Что происходит тогда? Очень простая штука: наш вагончик тут же «переводят на запасной путь», путешествуя по которому, он описывает круг специально рассчитанного размера и возвращается к диспетчеру как раз в тот момент, когда его нужно было бы запускать повторно. Диспетчер приостанавливает отправку на линию новых вагончиков и пропускает вперед прибывший «новый-старый» вагончик. Если к моменту повторного прибытия на исполняющие устройства данных там так и не окажется, микрооперация снова отправится на запасной путь и будет нарезать круги до тех пор, пока нужные данные не появятся. При этом по основному пути могут исполняться другие инструкции, независимые от первой. Получается простое и вроде бы эффективное решение. Хотя стоп! Эффективное ли? Занимавшаяся изучением реплея группа экспертов[Replay: неизвестные особенности функционирования ядра NetBurst
[Закрыть].] убедительно показала, что подобная незамысловатая техника приводит к нетривиальным и крайне интересным эффектам вроде «затягивания» в петли реплея целых цепочек данных (вплоть до полного зацикливания – deadlock’а!) и перегрузки исполнительных устройств из-за необходимости многократно исполнять некоторые инструкции. В итоге процессор архитектуры NetBurst «тормозит» даже при отсутствии ошибок предсказания – просто в силу того, что несвоевременно запущенные цепочки инструкций приходится переисполнять целиком, вместо того чтобы переисполнить одну-единственную «неудачную» инструкцию. Вдобавок, поскольку исполнительные устройства греются больше всех остальных узлов процессора, то непрерывная прогонка через них потока инструкций, данные для которого не подготовлены, приводит еще и к тому, что процессор не просто «тормозит», а вовсю греется. Не очень приятные эффекты, но это та цена, которую уплатила Intel за разработку процессора, умеющего работать на очень высоких тактовых частотах. И если учесть успех процессоров на ядре Northwood – цена вполне оправданная. К сожалению, непомерное тепловыделение NetBurst-процессоров начиная с некоторого момента замедлило, а потом и вовсе остановило рост тактовой частоты, так что сегодня минусы скорее перевешивают плюсы этой, несомненно, опередившей свое время архитектуры.
Просуммируем все сказанное. Теоретически процессор архитектуры NetBurst способен обрабатывать четыре инструкции за такт (два «быстрых» ALU, работающих на удвоенной частоте). При тактовой частоте от 2,53 до 3,8 ГГц столь высокий показатель должен был бы вывести NetBurst-процессоры в лидеры по производительности, если бы не недостаточно быстрый Front-end, неспособный обеспечить больше трех микроопераций за такт; если бы не крайне ограниченный набор «быстрых» инструкций, в которых вплоть до ядра Prescott не входила, например, широко используемая простая операция битового сдвига[Кстати, даже в Prescott битовый сдвиг поддерживает только одно Fast ALU из двух. Это и ряд других ограничений связаны с оригинальной организацией 32-битного Fast ALU в виде двух «сдвоенных» 16-битных ALU]; если бы не наличие всего лишь одного (!) блока ALU и одного блока FPU, умеющих работать со «всей остальной» арифметикой (причем целочисленное умножение вплоть до того же Prescott, тоже выполнялось в FPU!); если бы не многочисленные штрафные такты, возникающие, например, при обращении к «невыровненным» данным в оперативной памяти; если бы не система реплея… если бы не десятки разных «если», подрезающих этой архитектуре крылья.
Мнения: предположительные характеристики процессоров будущего
Информация о разработке преемника существующего решения AMD – ядра K9 – впервые появилась в 2003 году. На сегодняшний день почти доподлинно известно, что:
– K9 будет традиционным x86-процессором, с набором инструкций AMD64, поддержкой виртуализации и технологии безопасности LaGrande.
– K9 будет многоядерным CPU; вероятно, с общим для ядер L2-кэшем.
– K9 будет работать с двухканальной оперативной памятью DDR-II. При этом возможно, что предназначенные для многопроцессорных систем K9 будут выпускаться в нескольких вариантах – с интегрированным контроллером памяти и без него: вариант без ИКП будет дешевле. Более того, возможен и обратный вариант: покупка относительно дешевого контроллера памяти без процессора. Скажем, можно будет установить в 4P-материнскую плату один процессор с ИКП и три дешевых модуля ИКП – получится поддержка очень большого объема оперативной памяти (например, 64 Гбайт) задешево. Естественно, что устанавливаться все эти «разновидности» и «контроллеры» будут в один и тот же стандартный сокет.
– Число линков HyperTransport в K9 увеличат (вероятно, до пяти), что позволит легко создавать на основе K9 более чем восьмипроцессорные системы и повысит производительность четырех– и восьмипроцессорных серверов.
– Количество исполняемых за такт инструкций – больше трех.
– Удвоенное количество блоков FADD и FMUL позволит удвоить производительность при вычислениях в SSE2 с плавающей точкой.
Интересные, но маловероятные слухи говорят также о том, что в K9 появится:
– Одновременная поддержка до восьми спекулятивных ветвлений, позволяющая, как в процессоре Itanium, одновременно просчитывать несколько ветвей программного кода, избегая таким образом полного сброса конвейера при ошибке предсказания перехода.
– Введение трех специальных блоков SSE в дополнение к трем существующим блокам ALU и трем блокам FPU.
– Поддержка кэш-памяти третьего уровня (L3).
– HyperTransport 2.0; улучшенный протокол когерентности кэшей (MOESI+).
– Специальные буферы – суперкэши нулевого уровня, напрямую доступные исполнительным устройствам для сохранения промежуточных результатов и позволяющие сократить время на пересылку и сохранение данных при работе с плавающей точкой.
– Возможность переброски mOP’ов в многоядерных процессорах с конвейера одного ядра на конвейер другого. То есть двухъядерный процессор будет работать быстрее даже в однопоточных (!) приложениях.
– Сжатие на лету данных, хранящихся в кэш-памяти процессора, позволяющее увеличить эффективный объем кэша.
– 15 стадий целочисленного конвейера, 20 стадий – для вычислений с плавающей точкой.
– Trace Cache.
– Возможен интегрированный в крышку процессора тепловой насос – элемент Пельтье, увеличивающий эффективность теплоотдачи от кристалла CPU.
– Срок появления на рынке прототипов – второе полугодие 2006 года.
С Intel ситуация интереснее. От развития преемника архитектуры NetBurst – процессорного ядра Tejas (в котором, по слухам, должен был появиться – страшно представить – аж 50-стадийный конвейер), корпорация после долгих размышлений отказалась. Последним процессором «Пентиум четвертой» архитектуры станет выпускающийся по 65-нм технологическому процессу процессор Presler (Pentium D)/CedarMill (Pentium 4), в котором Intel всего лишь исправит допущенные при проектировании ядра Prescott ошибки. Например, появится поддержка маленьких коэффициентов умножения. Напомню суть проблемы: ядро Prescott, которое должно было покорить рубеж едва ли не в 5 ГГц, не позволяет использовать коэффициенты умножения, меньшие 14. Ну вот не предполагали разработчики, что они понадобятся: для частот 3-5 ГГц самый актуальный диапазон множителей – от 15 до 25. Но когда стало понятно, что из-за чрезмерного тепловыделения новое ядро не сумеет покорить даже 4-гигагерцовый рубеж, то невозможность процессоров с 800-МГц системной шиной работать на частоте меньше 2,8 ГГц, а процессоров с 1067-МГц шиной – на частоте менее 3,73 ГГц превратилась в серьезную проблему, не позволяющую массово ввести быструю шину и реализовать эффективные технологии энергосбережения. Появится и поддержка технологий виртуализации. Но это все мелочи, такая же «доработка» архитектуры, которой являлся в свое время пришедший на смену революционному, но неудачному Wilamette неновый, но удачный Northwood. Интереснее, что станет следующим Большим Шагом в развитии архитектур Intel.
Недавно обнародованные технические характеристики предполагаемого преемника NetBurst – процессоров Conroe, Merom и Woodcrest – таковы:
– За основу взят Pentium M (архитектура P6). Сохранен механизм наслоения микроопераций (когда одна операция распадается на несколько микроопераций – как, например, в K8, где mOP может порождать два ROP’а, один из которых задействует ALU, а другой – AGU).
– Новый широкий конвейер, напоминающий конвейер K8, но рассчитанный не на тройки, а на четверки инструкций. Длина конвейера – 14 стадий.
– Поддержка технологии EM64T, технологий виртуализации VT-x и безопасности LaGrande.
– Общий для многоядерных процессоров кэш второго уровня.
– Улучшенная подсистема памяти с эффективными схемами предвыборки и разрешения конфликтов по адресам при одновременном чтении-записи в память.
Больше пока ничего не известно: слишком уж мало времени прошло с момента анонса. Но судя по всему, получится нечто изрядно напоминающее сегодняшний Athlon 64, только без интегрированного контроллера памяти. Поживем – увидим: предполагаемый срок появления на рынке новых процессоров – второе полугодие 2006 года.