Страница 7 из 8 AMD Athlon 64 / Opteron (K8) После выхода из декодера сформированные группы по три МОПа помещаются в буфер переупорядочения ROB, который может содержать до 24 групп (72 МОПа). Новая группа МОПов также копируется в очереди планировщика, из которых операции будут запускаться на исполнение. В процессоре K8 имеется две очереди (буфера) планировщика: для целочисленных/адресных операций (ALU/AGU), и для операций арифметики с плавающей точкой (FPU). МОПы выбираются на исполнение из этих очередей во внеочередном порядке, по мере готовности аргументов операций (Рис. 10). Рис. 10 Очередь (буфер) планировщика для целочисленных и адресных операций состоит из трёх независимых очередей, по одной очереди на каждую позицию МОПа в группе. Длина каждой очереди — 8 элементов. Элемент очереди может содержать 2 РОПа (редуцированные операции, микрооперации), на которые расщепляется МОП — один арифметический и один адресный. Простая целочисленная операция преобразуется только в арифметическийh2 РОП, операция типа Load-Op, Op-Store или Load-Op-Store — в арифметическийh2и адресный РОПы, а операция загрузки (Load) или выгрузки (Store) — только в адресный РОП. Также выделяется элемент очереди для операции с плавающей точкой с загрузкой (Load) или выгрузкой (Store) — для неё тоже заполняется только адресный РОП. Каждая из трёх очередей связана с двумя отдельными функциональнымиh2устройствами, приписанными к этой очереди — целочисленным (ALU)h2h2h2 и адресным (AGU). По мере готовностиh2 операндов РОПы отсылаются на исполнение в соответствующее устройство.h2 В каждом такте из каждой очереди может быть отправлен на исполнениеh2 один арифметический РОП и один адресный РОП (в общем случае из разных элементов очереди). После обработки адресного РОПа в AGU формируетсяh2 запрос в устройство загрузки/выгрузки (Load/Store Unit) для последующего совершения операции доступа в память. В каждом такте может выполниться до двух операций 64-битной загрузки из L1-кэша либо одна загрузка и одна выгрузка. МОПы операции целочисленного умножения всегда помещаются декодером в первые две позиции группы и выполняются совместноh2в двух соответствующих устройствах ALU. В остальном функциональныеh2устройства для каждой из трёх очередей идентичны. Латентность большинства целочисленных операций составляет 1 такт. Таким образом, позиция МОПа в группе, сформированной декодером,h2 однозначно определяет номер очереди планировщика, в которую он будетh2 помещён, и номер устройства ALU и/или AGU, в которое он будетh2отправлен на исполнение. Изменение порядка выполнения операций можетh2производиться только в пределах каждой очереди. Жёсткая привязкаh2МОПов к очередям может привести к тому, что готовый к выполнениюh2МОП попадёт в такую очередь, где функциональные устройства занятыh2обработкой предшествующих операций, в то время как устройства наh2соседних очередях простаивают. Это приведёт к снижению производительностиh2процессора из-за неполной загрузки устройств и возрастания времени выполнения операций. Также возможна ситуация, когда одна из очередей переполнена МОПами, ожидающими результатов выполнения какой-то долгой операции — в этом случае новая группа из трёх МОПов не сможет быть размещена в очередях, несмотря на то, что остальные очереди свободны. Правда, вероятность такой ситуации не очень велика — для её появления необходимо, чтобы операции, зависимые друг от друга и образующие цепочку, попадающую в одну очередь, следовали в коде программы с шагом, равным трём. В принципе подобные проблемы могут легко решаться транслятором, который может разносить зависимые операции по разным позициям в формируемых группах МОПов и тем самым обеспечивать более сбалансированное распределение операций по очередям. Буфер планировщика для операций плавающей арифметики устроен совершенно иначе. Он организован в виде отдельнойh2 очереди, состоящей из 12 элементов (строк).h2h2h2 Каждая строка состоит из трёх позиций — по одной на каждую позицию МОПа в группе. Если вновь поступившаяh2h2 группа МОПов содержит хотя бы одну операцию с плавающей точкой, то для неё отводится новая строка в буфере. РОПыh2h2h2 (микрооперации) плавающей арифметики помещаются в позиции строки, соответствующие позициям исходного МОПаh2 в группе (остальные позиции остаются незанятыми). В отличие от очереди ALU/AGU, эти позиции не связаны с конкретными функциональнымиh2устройствами. Функциональных устройств FPU тоже три, но ониh2 разделяются по типам — FADD для операций сложения,h2 FMUL для операций умножения, и FMISC — для пересылок и прочих вспомогательных операций. МОПы плавающей арифметики, содержащие загрузку или выгрузку, попадают и в очередь планировщикаh2 ALU/AGU (адресный РОП), и в очередь планировщика FPUh2 (арифметический РОП). Если операция является простой загрузкой и не содержит арифметической части, то в FPU она может выполняться в любом из трёх устройств. Однако это не относится к загрузкам XMM-регистров в режиме SSE — ониh2 всегда выполняются в устройстве FMISC. Из-за этого темпh2 в две загрузки за такт в режиме SSE может быть достигнутh2h2h2 лишь при чередовании операций простой загрузки (Load) с операциями загрузки с умножением или сложением (Load-Op). РОПы отсылаются на исполнение в соответствующие функциональные устройства FPU по мере готовности операндов. В каждом такте в каждое устройство может быть отправлен один РОП. Некоторые РОПы могут исполняться в различных функциональных устройствах — в этом случае алгоритм выборки пытается сформировать оптимальный набор операций для запуска на исполнение в текущем такте. Однако в ряде случаев этот алгоритм не может совместить в одном такте две операции, если они могут претендовать на общее функциональное устройство. Например, если есть по одной операции для устройств FADD и FMUL, и три операции универсального типа FADD/FMUL/FMISC, то в одном такте алгоритм запустит операции FADD и FMUL, а в другом — все три универсальные операции, разнеся их по трём устройствам. Аналогично, если есть две операции целочисленного сложения MMX/SSE2 (могут исполняться в устройствах FADD и FMUL) и две операции умножения (только FMUL), то в одном такте запустятся обе операции сложения, а в двух последующих — по одной операции умножения (вместо того, чтобы совместить в двух тактах по одной операции сложения и умножения). Когда все «непустые» РОПы из строки отправляются на исполнение,h2h2h2h2h2 эта строка удаляется и очередь укорачивается, освобождая место для новой группы РОПов. Тем самым очередь планировщика FPU по своей организации напоминаетh2игру «Тетрис» - только в ней удаление целой строки происходит при её опустошении (а не при заполнении, как в «Тетрисе»). Эффективная вместимость очереди планировщика зависит от плотности размещения операций арифметики с плавающей точкой в коде. Для кода, состоящего исключительно изh2 таких операций, формальная вместимость очереди составитh2 36 РОПов. Однако на практике такая плотность операцийh2 FPU недостижима, поскольку в любом алгоритме обязательноh2 будут присутствовать вспомогательные операции для работыh2 с индексами массивов и для организации циклов. Кромеh2 того, часть очереди может быть занята РОПами, которыеh2 уже отправлены на исполнение, но ещё не проверены наh2 предмет окончательной готовности операндов (между диспетчеризациейh2 РОПа и его проверкой проходит 2-3 такта). С учётом резервированияh2 одной строки для вновь поступающей группы операций эффективныйh2 размер очереди составляет приблизительно 8 элементов. Этоh2 соответствует 24 РОПам для идеализированного кода, состоящегоh2 из одних операций FPU, и 16 РОПам для более реалистичного кода,h2 содержащего две операции FPU в каждой группе из трех МОПов. Для менее плотного кода вместимость очереди будет ещё ниже, однако в этом случае требования к буферу внеочередного исполнения снижаются.h2 В целом очередь планировщика FPU выглядит как достаточно эффективно организованная «рыхлая» структура с ассоциативным доступом. Каждое их двух основных устройств плавающей арифметики — сложения (FADD) и умножения (FMUL) — может выполнять одну операцию за такт с латентностью, равной четырём. С учётом того, что для упакованных режимов SSE одна машинная инструкция преобразуется декодером в два МОПа, предельный темп выполнения операций FPU для этого режима совпадает с темпом для скалярного режима и составляет два МОПа за такт (при чередовании операций сложения и умножения). Это соответствует четырём 32-битным арифметическим операциям за такт для упакованных режимов SSE и 3DNow!, и двум операциям за такт для прочих режимов — 64-битного упакованного SSE2 и всех скалярных (x87 и SSE/SSE2). Следует отметить, что на практике во внутреннем цикле возможно достижение уровня только в 1.8-1.9 арифметическую операцию за такт. Это связано с тем, что на каждую пару операций умножения-сложения необходима как минимум одна дополнительная операция загрузки из памяти, что не оставляет места в группах из трёх инструкций для операций организации циклов, предвыборки из памяти и прочих, а также может привести к определённым ограничениям скорости работы декодера. Таким образом, подсистема внеочередного исполнения операцийh2h2 и набор функциональных устройств в процессореh2h2 AMD K8 организованы существенно несимметричным образом, с разделением на блок целочисленной/адресной арифметики ALU/AGU и блок арифметики с плавающей точкой FPU. Это отличает данный процессорh2 от других, не имеющих такого явного разделения. В сочетании со «статическим» разбиением потока МОПов на группы по 3 элемента и с привязкойh2 очередей и функциональных устройств ALU/AGU к позициям этих элементов, такая организация позволила упростить структуру процессора. В результате выделения обработки операций плавающей арифметики в отдельныйh2 блок сократилось число этапов конвейера целочисленной обработки,h2 что критично для операций условного перехода (в случаях неправильного предсказания направления перехода). Обратной стороной такой организации является необходимость обеспечения избыточного количества идентичныхh2 универсальных функциональных устройств ALU/AGU, а также разнесения МОПов, ожидающих исполнения, на три короткие независимые очереди, что может привести к несбалансированной загрузке устройств и к снижению темпа исполнения операций. |