PC Magazine/RE logo (С) СК Пресс 12/95
PC Magazine September 12, 1995,p. 102

P6: взгляд внутрь

Ник Стам


В P6 используются почти все известные методы повышения вычислительной производительности. Но такой целенаправленный подход имеет и свои недостатки. Мы представляем вам подробное описание самого сложного на сегодня процессора семейства x86.

Разработка сложного современного процессора представляет собой трудный процесс поиска компромиссов: необходимо найти верные методы оптимизации производительности, не усложняя при этом изделие настолько, чтобы производство его стало практически неосуществимым. В процессоре P6 специалисты фирмы Intel воплотили весьма дерзкий подход к разработке архитектуры, сделав ее одновременно суперскалярной и суперконвейерной и наделив возможностями исполнения с изменением последовательности, отображения регистров, предсказания переходов, исполнения по предположению и многими другими.

Intel объединяет все эти технические термины в одно простое выражение для маркетинга - "динамическое исполнение" - которое отражает способность P6 оптимизировать исполнение программы, предсказывая ее дальнейший ход, выбирая лучший порядок исполнени команд и выполняя некоторые команды до разрешени условия перехода.

В P6 также реализована необычная архитектура шины, которая, помимо прочего, располагает встроенным в один корпус с ЦП кэшем второго уровня, работающим на частоте процессора.

Очевидно, что P6 оптимизирован для 32-разрядных, а не 16-разрядных программ. По утверждению фирмы Intel, при работе с 32-разрядными прикладными программами и 32-разрядными операционными системами, P6 показывает производительность примерно на 40-60%, чем Pentium с такой же тактовой частотой. Однако, при выполнении существующих 16-разрядных программ P6 будет работать медленнее, чем Pentium с такой же частотой. Чтобы понять, почему это происходит, давайте детально ознакомимся с микроархитектурой P6.

ДВА СПОСОБА ПОВЫШЕНИЯ ПРОИЗВОДИТЕЛЬНОСТИ

Существуют два подхода, которые позволяют создать высокопроизводительный микропроцессор. Один из них - проектировать устройство с высокой тактовой частотой; повышение частоты увеличивает число операций, которые ЦП может выполнить за единицу времени. Альтернативный путь - увеличение степени параллелизма процессора - позволяет выполнять больше операций в течение каждого периода тактовой частоты.

При создании P6 фирма Intel решила применить оба этих подхода. Высокая тактовая частота P6 достигаетс благодаря методу, называемому суперконвейеризацией (superpipelining), одновременно с этим предусмотренный в P6 механизм суперскалярного исполнения с изменением последовательности позволяет обрабатывать большее число команд за один такт, чем может Pentium.

Суперконвейеризация расширяет базовую концепцию конвейерной обработки, впервые реализованную в моделях семейства x86, начиная с процессора Intel 486. Конвейерные микропроцессоры выполняют команды подобно сборочной линии: полная обработка каждой инструкции занимает несколько тактов, но, разбивая процесс на несколько этапов и начиная выполнение следующей команды сразу вслед за тем, как предыдущая команда пройдет первый этап, можно быстро выдать несколько завершенных команд. Большинство команд в процессорах 486 и Pentium проходят через стандартный пятиступенный конвейер.

Суперконвейеризация делит ступени стандартного конвейера на более мелкие части; с увеличением числа ступеней каждая отдельная ступень выполняет меньшую работу и, следовательно, содержит меньше аппаратной логики. Уменьшение сложности логики уменьшает задержку распространения (propagation delay) - временной интервал между поступлением набора входных воздействий на входы схемы и появлением результирующих сигналов на ее выходах. Благодаря более коротким задержкам распространения становится возможным повышение частоты: как сообщает Intel, при одинаковой технологии производства частота суперконвейерного процессора P6 может быть на треть выше, чем у Pentium. Поэтому, когда Intel перейдет на 0,35-мкм технологию производства P6, в настоящее время используемую для 133-МГц процессоров Pentium, значение частоты около 180 МГц станет легко достижимым.

Суперконвейерная архитектура имеет серьезный недостаток. Команды, которые вынуждают P6 очищать свои конвейеры, а в их число входят неправильно предсказанные переходы и операции, подобные тем, что выполняют загрузку сегментных регистров (оба случа описаны ниже), могут существенно снизить производительность.

ВНУТРИ КОНВЕЙЕРА

Конвейер P6 - сложное устройство, насчитывающее 14 ступеней, разделенных на три блока. Входной блок упорядоченной обработки (in-order front end), отвечающий за декодирование и обработку команд, состоит из восьми ступеней. Ядро исполнения с изменением последовательности (out-of-order core), где собственно и происходит выполнение команд, имеет три ступени. И конвейер вывода команд из последовательности (in-order retirement) состоит из трех ступеней. Изящество архитектурного решения P6 состоит в том, что каждый из этих блоков работает достаточно самостоятельно.

В то время как классический конвейер позволяет выполнить в каждом такте одну команду, несколько конвейеров могут быть объединены в суперскалярную архитектуру, способную обрабатывать и исполнять более одной команды за такт. Pentium стал первым двухпотоковым суперскалярным процессором x86. Он имеет два отдельных конвейера - каждый со своей собственной аппаратной логикой - и таким образом, может исполнять до двух команд за такт. Но Pentium налагает несколько ограничений на условия, при которых две команды могут обрабатываться одновременно (вот почему фирма Intel настаивает, что перекомпиляция программ для Pentium с учетом этих ограничений - необходимое условие дальнейшего повышения производительности.)

Благодаря трехпотоковой суперскалярной архитектуре процессор P6 превосходит Pentium по производительности. Но в P6 не просто добавлен еще один конвейер; он принципиально отличается от процессора Pentium. P6 преобразует команды x86 во внутренние RISC-подобные команды, называемые микрокомандами (micro-ops). Это позволяет устранить многие ограничения, свойственные набору команд x86 - такие, как нерегулярность кодирования команд, операции целочисленных пересылок регистр-память и переменная длина непосредственных операндов.

В конечном счете микрокоманды передаются в механизм исполнения с изменением последовательности, который, располагая их таким образом, что команды, не готовые к исполнению, не вызывают "зависания" конвейеров и не препятствуют началу обработки команд, поступающих вслед за ними. Механизм исполнения с изменением последовательности P6 также отделен от начальных ступеней конвейера. Раздельная архитектура повышает эффективность суперскалярных операций, вызывая меньшее число блокировок конвейера и накладывая меньше ограничений при обработке по сравнению с Pentium.

ТРАНСЛЯЦИЯ КОМАНД x86

Выборка кода и трансляция его в микрокоманды происходят на шести первых ступенях конвейера P6. Процесс начинается, когда блок выборки команд (instruction fetch unit) P6 считывает 64 байт кода (две строки кэша) из первичного кэша команд P6, в соответствии с содержимым буфера адреса перехода (branch target buffer, BTB). Блок выборки команд использует текущий указатель команды, чтобы найти первую команду x86, а затем считывает 16 байт, начина с этой ячейки памяти, выравнивает их и передает на три параллельных дешифратора.

Зачем производить выборку 64 байт, если используютс только 16? Это необходимо потому, что кэш команд имеет 32-разрядную строковую организацию, и строка (line) - минимальный блок информации, который процессор может извлечь из кэша. Если нужная команда находится в конце первой строки кэша, то вторая строка предоставляет оставшиеся байты, необходимые для заполнения 16-байт буфера без задержки.

Дешифраторы преобразуют команды x86 в микрокоманды. В P6 имеются три параллельных дешифратора - два из них "простые", а третий "сложный". Простые дешифраторы обрабатывают команды x86, транслируемые в единственную микрокоманду. Сложный дешифратор работает с командами, которым соответствуют от одной до четырех микрокоманд. Некоторые особенно сложные команды невозможно непосредственно декодировать даже сложным дешифратором, они передаются в планировщик последовательности микрокоманд (microcode instruction sequencer, MIS), генерирующий необходимое число микрокоманд.

Если простой дешифратор встречает команду, котора не поддается трансляции, то в конечном счете она оказывается в сложном дешифраторе либо в планировщике последовательности микрокоманд. Такая пересылка слегка замедляет дешифрацию, но, возможно, не сказывается на исполнении благодаря буферизации с помощью станции-резервуара, рассматриваемой ниже.

Дешифраторы способны генерировать в общей сложности шесть микрокоманд за такт, если сложные и простые команды безупречно выравнены их соответственными дешифраторами, но в более типичном случае из всех трех дешифраторов за один такт выдаются три микрокоманды. (Именно поэтому Intel утверждает, что P6 имеет трехпотоковый суперскалярный механизм.) Как правило, в среднем этим трем микрокомандам соответствуют чуть меньше трех команд x86.

ОТОБРАЖЕНИЕ РЕГИСТРОВ

После того как команды будут декодированы и преобразованы в микрокоманды, седьмая ступень конвейера пересылает их в таблицу псевдонимов регистров (register alias table, RAT), чтобы выполнить отображение регистров. Отображение регистров помогает ослабить влияние ложных взаимозависимостей (false dependencies), которые могут снизить производительность в процессоре с изменением последовательности исполнения. Например, двум командам может понадобиться произвести запись в один и тот же регистр; без отображения регистров их невозможно будет исполнить вне очереди, так как более поздняя команда не может быть обработана до завершени более ранней команды.

Взаимозависимости, подобные этой, особенно часто встречаются в программах x86, потому что архитектура x86 предусматривает только восемь 32-разрядных регистров общего назначения (в противоположность этому, большинство RISC-процессоров содержат 32 и более регистров общего назначения). С таким малым числом регистров вероятность того, что две соседние команды будут использовать один регистр, относительно велика.

При отображении регистров происходит преобразование программных ссылок на архитектурные регистры в ссылки на больший набор физических регистров. (P6 в действительности содержит 40 физических регистров, реализованных в виде буфера восстановлени последовательности, описанного ниже.) По существу, процессор "размножает клонированием" ограниченное число программируемых, архитектурных регистров и отслеживает, какие клоны содержат наиболее поздние значения. Это предотвращает задержки, которые в противном случае были бы внесены в процесс обработки команд ложными взаимозависимостями в результате конфликтующих обращений к регистрам.

Отображение регистров не позволяет, однако, обойти истинные взаимозависимости, появляющиеся, когда входные данные одной команды зависят от результата выполнени предыдущей команды. В этом случае просто не существует способа продолжать исполнение команды до тех пор, пока не будет получен нужный результат. И все же методы, подобные продвижениям данных и результатов (data and result forwarding), могут ослабить даже влияние истинных взаимозависимостей, и в P6 они используются.

ИСПОЛНЕНИЕ С ИЗМЕНЕНИЕМ ПОСЛЕДОВАТЕЛЬНОСТИ КОМАНД

После отображения регистров микрокоманды пересылаются в структуру, именуемую буфером восстановления последовательности (reorder buffer, ROB, описывается ниже), а также ставятся в очередь в специальном буфере команд, называемом станцией- резервуаром (reservation station), который расположен между ступенями дешифрования и исполнения. Выступая в роли резервуара, буфер хранит группу декодированных команд, с тем чтобы исполнительные блоки продолжали работать, даже если дешифраторы перестали работать. И наоборот, если устройства исполнения заняты, станция-резервуар предоставляет дешифраторам возможность продолжить работу. (В редких случаях, когда станция-резервуар заполняется, блок дешифрации может приостановить свою работу.)

В P6 может храниться до 20 микроопераций в единственной централизованной станции-резервуаре (чаще называемом центральным окном команд), обслуживающей все его исполнительные блоки. Резервуар напрямую соединяется со всеми 11 исполнительными блоками P6. Он может посылать максимум пять микрокоманд за такт, но при работе с типичными командными последовательностями x86 более вероятен непрерывный поток пересылок с интенсивностью три микрокоманды за такт.

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

Хотя термин "с изменением последовательности" подразумевает, что операции не выполняются строго в порядке, предусмотренном программистом, на самом деле это не так: "неупорядоченные" результаты вычисляются и сохраняются во временных буферах, размещенных на кристалле, и всегда записываются в архитектурные регистры и системную память в порядке, оговоренном программой. На этом этапе начинают играть важную роль ступени удаления (retirement stages) конвейера, рассматриваемые ниже.

P6 выполняет анализ потока данных, с тем чтобы определить, для каких микрокоманд уже готовы все операнды и они могут быть переданы в исполнительные блоки. Помимо станции-резервуара ключевая роль в управлении потоками данных принадлежит еще одной структуре P6 - буферу восстановления последовательности (ROB). ROB содержит 40 элементов, размером 254 байт каждый, и может хранить микрокоманду, два связанных с ней операнда, результат и несколько битов состояния. В ROB могут находиться микрокоманды как вещественного, так и целочисленного типа.

ВЫВОД

Команды, которые исполняются не в той последовательности, которая предписана программой, следует в конечном итоге расположить в должной последовательности - иначе процессор не всегда сможет получить правильные результаты. ROB сохраняет статус исполнения и результаты каждой микрокоманды. Микрокоманда выводится, и результаты заносятся в архитектурные регистры и память только после того, как станет известно, что предыдущие микрокоманды завершились.

Рассмотрим этот процесс. После того как команды были дешифрованы и регистры переименованы, микрокоманды помещаются в ROB - циклическую очередь FIFO - последовательно, в определяемом программой порядке. Это происходит тогда, когда эти же самые микрокоманды пересылаются в станцию-резервуар.

Последовательный процесс упорядочения очень важен для восстановления программного порядка микрокоманд после исполнения с изменением последовательности. Это обеспечивает упорядоченное обновление архитектурных регистров и ячеек памяти после завершения исполнения.

Тот факт, что и ROB, и станция-резервуар получают одни и те же микрокоманды в одно и то же время из дешифраторов - важный элемент архитектуры P6. Пока ROB следит за программной последовательностью микрокоманд, станция-резервуар сохраняет их в буфере и определяет момент, когда конкретная микрокоманда будет готова к пересылке в соответствующее устройство исполнения. (Микрокоманды готовы к пересылке, когда определены все их операнды.)

Результаты выполнения предыдущих микрокоманд можно использовать в качестве исходных операндов дл последующих, поэтому все результаты из каждого устройства исполнения посылаются назад в станцию-резервуар. По сути, P6 применяет сложную схему межсоединений, подобную матричному переключателю, которая связывает все выходные порты исполнительных блоков со станцией-резервуаром. Это позволяет продвигать (forward или bypass) результаты в другой исполнительный блок, которому данный результат требуется в качестве входного операнда, без задержки, вызванной обновлением и повторным чтением регистров.

Результаты из полных блоков также направляются назад в ROB, который определяет, готова ли микрокоманда к удалению. В процессе удаления происходит запись результатов - обновление архитектурных регистров и сохранение данных в памяти. ROB обеспечивает вывод всех микрокоманд в указанном программой порядке; максимальная скорость вывода - три микрокоманды за такт, что примерно соответствует средней производительности дешифраторов.

Операции записи в память также откладываются до той поры, пока вызвавшая их микрокоманда не будет выведена. Для этого в P6 предусмотрен буфер упорядочени обращений к памяти (memory order buffer - MOB), в котором по командам, выдаваемым устройствами записи в память, сохраняется информация о данных и адресах. MOB пересылает данные в память, лишь когда ROB уведомит MOB о том, что микрокоманда, произведшая запись в память, удаляется.

ВЛИЯНИЕ НА СКОРОСТЬ ВЫПОЛНЕНИЯ 16-РАЗРЯДНЫХ ПРОГРАММ

Потенциальные преимущества модели выполнени программ с изменением последовательности очевидны: она помогает обходить неопределенные состояния, способные помешать беспрепятственному прохождению команд через процессор. Но есть ситуации, в которых проявляютс серьезные недостатки этой архитектуры. Некоторые команды вызывают блокировку конвейера упорядоченной обработки, приостанавливая поступление и обработку последующих команд до тех пор, пока определенна команда не пройдет все оставшиеся ступени конвейера вплоть до завершения.

Команды загрузки сегментных регистров и ввода-вывода, операции с управляющими регистрами могут оказать разрушительное влияние на производительность даже такого процессора, как P6, с его многочисленными и глубокими конвейерами. P6 не может выполнять эти команды вне последовательности определяемой программой. Когда процессор встречает такую команду, он вынужден остановить обработку команд и выполнить "дренаж" конвейеров (завершить выполнение всех частично обработанных команд). Кроме того, необходимо очистить первые ступени конвейера от находившихся там команд, которые затем придется заново загружать. В итоге процессор теряет десятки возможностей обрабатывать команды.

Программа также может вызвать продолжительную блокировку процессора P6, попытавшись прочитать данные из регистра, после того как другая команда произвела запись в одну из частей этого регистра. В 16-разрядной программе, например, запись результата в AL и последующая попытка чтения из AX (16-разрядное надмножество 8-разрядного регистра) могут остановить процесс на семь или более тактов, если команда, выполнившая запись в частичный регистр, еще не была удалена. В 32-разрядной программе операции чтения из 32-разрядного регистра, следующие за операциями записи в 8- или 16-разрядные частичные регистры, также приводят к возникновению этой проблемы.

Компиляторы позволяют уменьшить вероятность остановов, связанных с использованием частичных регистров, но для составленных вручную ассемблерных программ остановы, вызванные операциями с частичными регистрами, довольно характерны. Операционная система Windows 3.1 и некоторые модули Windows 95 содержат программный код, составленный вручную на ассемблере, что может приводить к блокировкам процессора P6, вызванным обращениями к частичным регистрам.

Задержки в работе, связанные с использованием частичных регистров и загрузкой сегментных регистров могут снижать производительность в различной степени. Если обновление частичного регистра отстоит от последующей операции чтения из полного регистра на много команд, то блокировка может продлиться всего несколько тактов, так как запись в частичный регистр близка к удалению. Но если обновление частичного регистра вплотную примыкает к последующему чтению из полного регистра, продолжительность задержки составит по меньшей мере семь тактов относительно выходных сигналов дешифратора. В среднем блокировка может задержать обработку от 3 до 21 микрокоманд, что может соответствовать 21 команде x86.

Блокировки, вызванные использованием частичных регистров, и, по выражению фирмы Intel, "необоснованные" загрузки сегментных регистров - основные причины, из-за которых сегодняшние 16-разрядные прикладные программы не будут выполнятьс процессором P6 так же быстро, как 32-разрядные прикладные программы. Некоторые существующие 16-разрядные программы содержат множество обращений к частичным регистрам или большое число операций загрузки сегментных регистров, которые могут вызвать останов.

Фирма Intel приняла решения оптимизировать P6 дл 32-разрядных программ много лет назад, ожидая, что 32-разрядные прикладные программы получат к 1995 г. очень широкое распространение. Позднее Intel решила, что устранение блокировок, вызванных использованием частичных регистров, с целью повышения скорости выполнения существующих 16-разрядных программ не оправдает себя, поскольку потребует дополнительной логики и усложнения архитектуры кристалла.

ПРЕДСКАЗАНИЕ ПЕРЕХОДОВ

Когда конвейеры работают вхолостую, снижаетс производительность, поэтому разработчики P6 реализовали сложную схему предсказания переходов, чтобы свести к минимуму влияние изменений последовательности выполнения программы. Существует две разновидности переходов: безусловные, всегда передающие управление по новому указанному адресу, и условные, которые меняют или не меняют ход выполнения программы в зависимости от результата сравнения или выполнения какого-либо другого условия. (Когда условный переход не выполняется, программа просто продолжает выполнение следующей по порядку команды.)

В типичной программе до 10% команд могут быть безусловными переходами, и еще 10-20% - представлять собой условные переходы. Безусловные переходы проблем не вызывают; процессор "уверен", что они будут выполнены и поэтому просто начинает выборку команд по указанному адресу. Команды условных переходов представляют гораздо большие трудности, потому что процессор не может "знать", будет ли переход выполнен или нет до тех пор, пока команда не пройдет исполнительную ступень конвейера.

Однако ожидание, пока команда ветвления покинет исполнительную ступень, означает отказ от возможности выборки и обработки многих команд. Процессору нужен некий алгоритм, который позволит ему "угадать", будет ли выполняться переход или нет. Если предсказание окажется верным, то исполнение продолжится с малой задержкой либо вовсе без нее. Если же предположение ошибочно, то частично выполненные команды придетс удалить из конвейера, а новые команды выбрать из области памяти с правильным адресом, декодировать и выполнить их. Это повлечет за собой существенное снижение производительности - особенно ощутимое в процессорах, которые, как P6, имеют многочисленные и глубокие конвейеры. Если P6 ошибается в предсказании перехода, он может потерять от 4 до 15 тактов.

Существуют два основных метода предсказани переходов - статический (static) и динамический (dynamic). Статические методы предсказания ветвлений слишком упрощены; они предписывают всегда выполнять или не выполнять определенные типы переходов. В некоторых процессорах (не принадлежащих к семейству x86) команды содержат "намек" на направление предполагаемого перехода, который компилятор может сделать на основе ожидаемого им поведения программы. Но в целом более эффективное решение - динамический алгоритм предсказания ветвлений, который на самом деле оценивает поведение команд перехода за предшествующий период времени (поскольку один и тот же переход часто выполняется более чем один раз, например, в цикле). Благодаря информации о предыстории предсказания будущих ветвлений могут делаться гораздо более точно. P6 применяет статические методы для предсказания поведени тех команд перехода, предыстория которых не была проанализирована с помощью динамических методов.

Как и в процессоре Pentium, в P6 используетс структура, называемая буфером адреса перехода (branch target buffer - BTB), и оба процессора применяют методы предсказания, основанные на битах предыстории ветвлений. Но, как утверждает Intel, предсказание ветвлений в P6 намного точнее: результативность достигает 90%, в то время как для Pentium она составляет 80%. (Другими словами, ошибочные предположения встречаются в P6 вдвое реже - примерно в 10%, а не в 20% случаев, как в Pentium.)

В P6 использован двухуровневый адаптивный исторический алгоритм, который не только регистрирует предысторию и предсказывает конкретные переходы, но может также предугадывать поведение групп команд переходов. Intel не вдается в подробности, но сообщает, что BTB процессора P6 может предсказывать четыре целевых адреса на строку кэш-памяти команд.

В большинстве высокопроизводительных процессоров, в том числе P6, возможности предсказания ветвлений усилены благодаря исполнению по предположению (speculative execution) - способности исполнять команды, следующие за командой условного перехода, еще не зная того, правильно ли был предсказан исход ветвления. Процессор не должен обновлять архитектурные регистры или память до тех пор, пока исполненные по предположению команды перехода не будут однозначно разрешены. Если какой-либо из переходов был предсказан неправильно, то процессор должен иметь возможность корректно отменить все выполненные команды, следующие за точкой ветвления. Для этого ROB процессора P6 просто отбрасывает исполненные по предположению команды, прежде чем они будут удалены. P6, как и другие современные процессоры, допускает несколько уровней предположения, предсказывая и отслеживая более одного целевого потока команд.

P6 также содержит специальную логику для обработки особого типа перехода - пары команд вызова-возврата из подпрограмм CALL/RET. Поскольку подпрограмма может быть вызвана из многих различных точек в программе, то трудно предсказать, откуда процессор должен производить выборку команд, встретив команду RET. Механизм предсказания, называемый стеком возвратов (return stack), помогает ослабить влияние подобных ситуаций; адрес команды, следующей за командой вызова, представляющий собой правильный адрес возврата дл этого конкретного вызова подпрограммы, помещается в стек. Таким образом, логика предсказания ветвлений может сообщить процессору, что после возврата из подпрограммы должна быть произведена выборка надлежащей команды.

БЛОК ВЫЧИСЛЕНИЙ С ПЛАВАЮЩЕЙ ТОЧКОЙ

Попытки повысить производительность P6 привели к ряду улучшений, внесенных в модель вычислений с плавающей точкой, используемую в процессоре Pentium. Блок вычислений с плавающей точкой P6 полностью конвейеризован, поэтому он несомненно должен превзойти Pentium при выполнении следующих одна за другой операций с плавающей точкой. Кроме того, средства динамического исполнения P6 часто позволяют "скрыть" относительно долгие периоды ожидания, свойственные операциям с плавающей точкой (они обычно занимают несколько тактов на стадии исполнения, в отличие от одного-двух тактов, требующихся для большинства целочисленных команд). Пока устройство вычислений с плавающей точкой занято, могут быть выполнены многие другие необходимые операции.

В P6 также устранен недостаток, представляющий собой наиболее уязвимое место блока вычислений с плавающей точкой процессор семейства x86: использование стековой модели. Набор команд x86 оперирует со значениями, находящимися на верхушке стека операндов, что заставляет программы часто применять команду FXCH (обмен вещественными числами) для доступа к информации, находящейся в других ячейках стека. В P6 предусмотрены специализированные аппаратные средства, которые обеспечивают эффективный доступ к любому элементу стека вещественных чисел, не внося дополнительных задержек.

Фирма Intel также работает над тем, чтобы повысить скорость исполнения так называемых множительно- аккумулятивных последовательностей (multiply-accumulate sequences), лежащих в основе многих алгоритмов обработки цифровых сигналов.

И ЭТО ЕЩЕ НЕ ВСЕ...

Нет сомнений в том, что процессор P6 раздвигает пределы возможностей сегодняшней суперскалярной архитектуры, и о его устройстве можно рассказать гораздо больше, чем позволяет отведенное нам журнальное пространство. Главным вопросом станет, какой выигрыш в производительности получат реальные прикладные программы от всех архитектурных усовершенствований? Обращайтесь к нашим оперативным службам, и вы получите последнюю информацию о производительности этого процессора.


Как работает P6

P6 выбирает и дешифрирует команды x86 и преобразует их в микро-команды, которые пересылаются в таблицу псевдонимов регистров (RAT). Затем они поступают в станцию-резервуар и буфер восстановлени последовательности, последовательно проходя по ступеням исполнения с изменением последовательности и, наконец, удаляются.

------------------------------------ | Встроенный кэш второго уровня (256 | | Кбайт или 512 Кбайт) | | | ------------------------------------ | | | | Внешняя Внешняя Шина Шина шина шина данных адреса данных адреса (64 бит (31 бит) (64 бит (36 бит) + ECC, | ------------------------ | + ECC, | 8 бит) | | Буфер упорядочения | ----------->| 8 бит) | | | ---> |обращений к памяти (MOB)| <--->| | | | | | | ------------------------ | | | | --------------------- <----- | | | |<-> | Блок интерфейса | ------------------------ | | |<--------|--> | шины |<---------> | Кэш данных (8 Кбайт) |------|----->| | | --------------------- ------------------------ <--->| | | ------------------------ | | ----------------------------------- | Блок интерфейса памяти |------|----->| | Блок выборки/декодирования команд | ------------------------ <--->| | | Кэш команд Указатель | |__________________________ | | (8 Кбайт) <-- на следующую | | | | команду | ------- ------------------------ | | ----------------------------------- | |Порт 4 | Блок памяти данных |->| | | | | |------> ------------------------ | | | | | | | | 16-байт буфер Буфер адреса | | ------------------------ | | выравненных перехода - | |Порт 3 | Блок генерации адреса| | | команд x86 содержит до | |------>| записи |->| | | | | 512 элементов | | ------------------------ | | | | |_______ | | | ------------------------ | | | |__ |_ | | Стан- |Порт 2 | Блок генерации адреса|->| | ------|------| --------|--------------- | ция- |------>| считывания | | | | Дешифратор команд x86 | | резер-| ------------------------ | | | | | | | вуар | ------------------------ | | | Простой Простой Сложный Блок | | (буфе-|Порт 1 | Блок целочисленных | | | | блок блок блок <->упорядо-| | ризу- |------>| операций | | | обработки обработки обработки чения | | ет | |_______________________ |<-->| | (1 микро- (1 микро- (от 1 до 4 команд | | 20 | | Блок выполнения | | | команда команда микро- | | мик- | | переходов | | | за такт) за такт) команд | | роко- | ------------------------ | | за такт) | | манд) | ----------------------- | ----------------------------------------- | |Порт 0 | Блок целочисленных | | | | | | | | | |------>| операций | | ---------------------------------------- | | | ----------------------| | | Таблица псевдонимов регистров | | | | Блок целочисленного | | | и блок распределения | | | | деления | | ---------------------------------------- | | | ----------------------| | | | | | Блок сложения с | | | | | | плавающей точкой | | | | | | ----------------------|<-->| | | | | Блок умножения с | | | | | | плавающей точкой | | | | | | ----------------------| | | | | | Блок деления с | | | | | | плавающей точкой | | | | | | ----------------------| | | | | | Блок сдвиговых | | | | | | операций | | | | | ----------------------- | | | |<------------------------------------| | | | ------------------------ | | | |<---- | Буфер восстановления |<----| | | | | последовательности | | | | | | (содержит до 40 | | | | | | элементов) | | | ------- |------------------------| | | | | Массив реальных | | |<----------------------------------->| регистров | | | В среднем 3 микрокоманды за такт ------------------------ | Шины результатов

P6 с точки зрения программиста

Ник Стам

Для программиста мало что изменилось в P6 по сравнению с Pentium. P6 не содержит новых регистров общего назначения, и для него предусмотрена лишь одна важная новая команда: CMOV, или пересылка по условию (conditional move). Пересылки по условию реализованы во многих RISC-процессорах; они позволяют компилятору минимизировать число команд ветвления, снижающих производительность. Но лишь немногие программисты, по всей видимости, будут применять команду CMOV для P6, поскольку это сделает их программы несовместимыми с более ранними ЦП фирмы Intel.

P6 также облегчает по сравнению с Pentium доступ к расположенным на кристалле регистрам, контролирующим производительность, но эта возможность представляет интерес в основном дл разработчиков компиляторов.

Предусмотренные в P6 средства динамического исполнения означают, что оптимизация программного обеспечения не столь важна для достижения максимальной производительности, как в процессоре Pentium. Но тем не менее есть некоторые правила программирования, основанные на здравом смысле, которыми вы можете воспользоваться с тем, чтобы полностью реализовать потенциал P6.

Избегайте считывать содержимое большого регистра (такого, как EAX) после записи в меньшую часть этого же регистра (например, AL). Это заставит P6 приостановить обработку команд, которые ссылаются на полный регистр, и всех последующих команд, до тех пор пока команда записи в частичный регистр не будет удалена, что может значительно снизить производительность (подробное объяснение см. во врезке "Почему P6 предпочитает NT").

Там, где это возможно, избегайте переходов. Задействуйте стек возвратов P6, использу команду RET, но не JMP в конце подпрограммы. И старайтесь сделать существующие переходы предсказуемыми, придерживаясь правил статического алгоритма предсказания ветвлений, принятых в процессоре P6.

Должным образом выравнивайте данные. Така оптимизация принесет пользу любому процессору.

Избегайте самомодифицирующихся программ. Выполнение программы, которая изменяет сама себя, может привести к тому, что процессор P6 очистит свои конвейеры, а код, находящийся в кэш-памяти, может стать недействительным.

Эти и многие другие приемы оптимизации детально рассмотрены в "белой книге" фирмы Intel, названной "Optimizations for Intel's 32-bit Processors." ("Способы оптимизации для 32-разрядных процессоров Intel").


Шина P6: быстродействующий интерфейс для многопроцессорных систем

Джон Клаймен

Одно из наиболее существенных отличий P6 от предшествующих ЦП семейства x86 - это способ его взаимодействия с внешним миром. Что же касаетс внутренней организации P6, то в нем отсутствует традиционное разделение кэш-памяти, что позволяет устранить ограничения, свойственные подсистеме памяти. Внешняя же шина P6 предполагает принципиально более совершенный метод доступа к системной памяти, некоторым быстродействующим устройствам ввода-вывода и другим процессорам в многопроцессорной системе и взаимодействия с ними.

Поддерживать работу высокопроизводительного ЦП на полную мощность - это значит исключить как можно большее число задержек, а один из наиболее негативно сказывающихся на функционировании процессора видов задержки обусловлен состояниями ожидания при обращениях к основной памяти, которая значительно уступает процессору в быстродействии. (Сравните: ИС динамического ОЗУ с временем доступа 80 нс не может "угнаться" за 133-МГц процессором, один такт которого составляет 7 нс.) Вот почему процессоры, начиная с модели 486, обычно работают со скоростными кэшами как встроенными (L1 - первого уровня, или первичными ), так и внешними (L2 - второго уровня, или вторичными). В кэш-памяти хранятся часто используемые команды и данные, и это помогает предотвратить прерывания работы процессора, вызванные временной недоступностью необходимых дл продолжения работы данных.

Емкость первичного кэша P6 не превышает емкости первичного кэша Pentium: в обоих устройствах отводится 8 Кбайт для команд и 8 Кбайт для данных. Для P6 этого вполне достаточно, поскольку конструкция его кэша второго уровня не имеет аналогов среди прочих серийно выпускаемых процессоров. Вторичный кэш P6 фактически стал частью самого процессора: он непосредственно соединен с кристаллом ЦП в процессе изготовления ИС. Выигрыш в производительности, достигаемый благодаря тесно связанному с процессором вторичному кэшу, избавляет от необходимости увеличения емкости первичного кэша.

Емкость кэша второго уровня P6 будет равна либо 256 Кбайт (при изготовлении по 0,6-мкм технологии), либо 512 Кбайт (при изготовлении по 0,35-мкм технологии). В любом случае процессор связан с вторичным кэшем шиной, работающей на частоте ЦП, которая может составлять от 133 до 200 МГц и, возможно, больше. ЦП самостоятельно ведет учет тегов кэша, показывающих, какая информация хранится в кэш-памяти. Это означает, что ЦП может извлекать информацию из вторичного кэша после всего лишь одного такта ожидания. В противоположность этому, даже для самых быстрых подсистем кэша второго уровн в системах на базе Pentium обычно требуется два такта ожидания в случаях, когда при обращении к памяти обнаруживается, что необходимая информаци отсутствует в первичном кэше.

Чтобы еще более снизить влияние "промахов" на производительность, кэш-память как первого, так и второго уровней в процессоре P6 - неблокируема (nonblocking). Отсутствие нужной процессору информации в обоих кэшах не мешает обработке последующих обращений к кэшу. (Непосредственно схемами кэш-памяти может быть обработано до четырех неудачных обращений в кэш, а с помощью буфера упорядочения обращений к памяти процессора может быть поставлено в очередь до 12 дополнительных обращений к памяти.) Неблокируемая кэш-память особенно хорошо подходит для работы совместно с логикой ядра исполнения с изменением последовательности, принятого в P6, так как позволяет большей части процессора функционировать во время выполнения операций с памятью, сопряженных с длительными периодами ожидания, которые иначе вызвали бы останов конвейера (как в процессоре Pentium).

Шина транзакций допускает перекрывающиеся запросы

Относительно большая емкость кэш-памяти первого и второго уровней помогает свести к минимуму потоки данных на внешней шине ЦП при обращениях к памяти, но тем не менее фирма Intel приложила максимум усилий, чтобы "расшить" потенциальные узкие места в подсистеме памяти. Рабочая частота внешней шины P6, как и внешней шины Pentium, составляет лишь долю частоты ЦП: в данном случае либо треть, либо четверть. (Здесь преследуется цель не увеличивать чрезмерно сложность системы, ограничив скорость шины частотой приблизительно 66 МГц.) Ширина шины данных остается равной 64 бит (еще 8 бит используются дл коррекции ошибок, и в результате общая ширина шины данных составляет 72 бит).

Новизна подхода, реализованного P6, заключается в способе, с помощью которого процессор взаимодействует с другими устройствами, соединенными с шиной, - такими, как подсистемы памяти, другие ЦП в мультипроцессорной конфигурации и устройства ввода-вывода. В нем воплощена концепция шины транзакций, способной обслуживать множественные ожидающие обработки запросы. Чтобы выполнить ряд последовательных обращений к внешней памяти, ЦП может послать несколько запросов в основную память, не дожидаясь ответа на каждый из них; когда память будет готова выдать требуемую информацию, контроллер памяти уведомит об этом процессор. Другие транзакции шины не будут блокированы в случае, если подсистема памяти задержится с ответом.

Устройства, которые соединены с шиной и могут выдавать запросы на использование шины, называютс агентами шины (bus agents). (P6 считается агентом шины.) Одновременно между всеми агентами шины может происходить до восьми транзакций, хотя каждый процессор P6 может выдавать и отслеживать не более четырех ожидающих обработки транзакций. Дополнительные транзакции - до 16 в общей сложности - могут помещаться в очередь внутри блока шинного интерфейса процессора.

Фирма Intel даже снабдила P6 механизмом, позволяющим откладывать транзакции шины на сравнительно длительное время (от микросекунд до нескольких минут, если в P6, вспомогательной логике и программном обеспечении предусмотрена возможность работы с такими задержками). Конкретный агент шины обслуживает ожидающие обработки транзакции в порядке их поступления, чтобы обеспечить корректное функционирование системы.

Хотя задержка обращения к памяти на одну миллисекунду и более кажется нецелесообразной с точки зрения производительности - процессор, скорее всего, исчерпает все задачи, которые могут выполняться независимо от данной информации - возможна ситуация, когда это оказывается особенно полезным, и возникает она в крупномасштабных мультипроцессорных системах.

Внутренняя архитектура P6 приспособлена дл "бесшовной" четырехканальной симметричной мультипроцессорной обработки. Это означает, что дл построения многопроцессорной системы на базе P6 в принципе нужно немногим больше чем просто соединить между собой выводы различных ЦП - не требуетс почти никакой дополнительной логики. В ЦП содержатс все необходимые для этого схемы обеспечени когерентности кэша и шинного арбитража. (Действительно, контроллер шины P6 содержит 89 000 транзисторов - намного больше, чем весь процессор 8088, который лег в основу первого IBM PC.)

Реализация механизма задержки ответа позволит разработчикам систем расширить сферу применения P6 за пределы четырехканальных мультипроцессорных систем. В частности, станет возможной кластерна мультипроцессорная архитектура, где несколько четырехканальных P6-машин соединяются через выделенную магистраль, используя такую технологию, как ATM.

Достоинства архитектуры процессора P6 позволяют ему стать серьезным конкурентом на этих рынках: он совместим со всеми распространенными мультипроцессорными операционными системами и реализует ту же логическую схему обработки прерываний для мультипроцессорных систем APIC (Advanced Programmable Interrupt Controller - усовершенствованный программируемый контроллер прерываний), что и высококлассные модели Pentium.

Различия в представлении сигналов

P6 столь необычен, что разработчики Intel даже решили отказаться от традиционных TTL-уровней электрических сигналов, которые обычно применялись в шинах ПК на протяжении многих лет. Вместо этого в P6 используется схема, известная как GTL+ (Gunning Transceiver Logic).

Схема GTL+ обладает многими весьма ценными преимуществами. Во-первых, она позволяет нескольким устройствам одновременно получать доступ к шине, не вызывая электрических конфликтов - важнейша характеристика, принципиально важная дл сетеподобной шинной архитектуры P6. Во-вторых, функционирование схем GTL+ не зависит от напряжени питания, а это означает, что Intel может изменять напряжение питания разных моделей P6, не внос изменений в конструкцию системы. В-третьих, GTL+ требует меньшей разности напряжений между высоким и низким логическими уровнями, чем ТТЛ, позвол повысить тактовую частоту. И в-четвертых, GTL+ более помехоустойчива и не столь чувствительна к задержкам распространения сигналов, избавляя от сложных временных взаимозависимостей между сигналами шины.

Независимость от напряжения питания

Независимость GTL+ от напряжения питания важна, поскольку в конечном итоге P6 будет выпускаться в различных вариантах, требующих различных значений напряжения питания. P6 имеет четыре выделенных вывода идентификации напряжения питания, на которых указывается напряжение питания процессора в цифровом виде. Соединив эти выводы со стабилизатором напряжения, разработчики систем могут использовать системные платы, позволяющие установку процессоров P6, рассчитанных на напряжение питания в диапазоне от 2,4 до 3,4 В.

Первые кристаллы P6, изготовленные по 0,6-мкм технологии, будут работать с 2,9-В источниками питания, но по мере перехода к технологии производства процессоров с меньшими геометрическими размерами напряжение питания будет снижаться.