Классический конвейер RISC

редактировать
Конвейер команд

В истории компьютерного оборудования, некоторые ранние сокращенные наборы команд компьютер центральные процессоры (ЦП RISC) использовали очень похожее архитектурное решение, теперь называемое классическим конвейером RISC . Этими процессорами были: MIPS, SPARC, Motorola 88000, а позже - условный CPU DLX, изобретенный для образовательных целей.

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

Содержание
  • 1 Классический пятиступенчатый конвейер RISC
    • 1.1 Выборка инструкции
    • 1.2 Декодирование инструкции
    • 1.3 Выполнение
    • 1.4 Доступ к памяти
    • 1.5 Обратная запись
  • 2 опасности
    • 2.1 Опасности конструкции
    • 2.2 Опасности данных
      • 2.2.1 Решение A. Обход
      • 2.2.2 Решение B. Блокировка трубопровода
    • 2.3 Опасности управления
  • 3 Исключения
  • 4 Обработка ошибок кэша
  • 5 Ссылки
Классический пятиступенчатый конвейер RISC
Базовый пятиступенчатый конвейер в машине RISC (IF = Instruction Fetch, ID = Instruction Decode, EX = Execute, MEM = доступ к памяти, WB = обратная запись в регистр). Вертикальная ось - последовательные инструкции; горизонтальная ось - время. Таким образом, в зеленом столбце самая ранняя инструкция находится на стадии WB, а последняя инструкция выполняет выборку команды.

Выборка инструкции

Инструкции находятся в памяти, для чтения которой требуется один цикл. Эта память может быть выделенной SRAM или кэшем инструкций Cache. Термин «задержка» часто используется в информатике и означает время от начала операции до ее завершения. Таким образом, выборка команды имеет задержку в один тактовый цикл (при использовании SRAM с одним циклом или если инструкция была в кэше). Таким образом, во время этапа выборки инструкций из памяти команд выбирается 32-битная инструкция.

Программный счетчик, или ПК, представляет собой регистр, который содержит адрес, представленный в памяти команд. В начале цикла адрес представляется в память команд. Затем во время цикла инструкция считывается из памяти инструкций, и в то же время выполняется расчет для определения следующего ПК. Расчет следующего ПК выполняется путем увеличения ПК на 4 и выбора того, следует ли использовать его в качестве следующего ПК или, альтернативно, использовать результат вычисления перехода / перехода в качестве следующего ПК. Обратите внимание, что в классическом RISC все инструкции имеют одинаковую длину. (Это то, что отделяет RISC от CISC). В исходных проектах RISC размер инструкции составляет 4 байта, поэтому всегда добавляйте 4 к адресу инструкции, но не используйте PC + 4 в случае принятого перехода, перехода или исключения (см. с задержкой филиалы, ниже). (Обратите внимание, что некоторые современные машины используют более сложные алгоритмы (прогнозирование и прогнозирование целевого перехода ), чтобы угадать адрес следующей инструкции.)

Декодирование инструкций

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

Все инструкции MIPS, SPARC и DLX имеют не более двух входов регистров. На этапе декодирования индексы этих двух регистров идентифицируются в инструкции, и индексы представляются в регистровую память как адрес. Таким образом, два названных регистра считываются из файла регистров . В дизайне MIPS регистровый файл имел 32 записи.

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

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

На этапе декодирования потребовалось довольно много оборудования: MIPS имеет возможность ветвления, если два регистра равны, поэтому 32-битное дерево AND запускается последовательно после чтения файла регистров, создавая очень длинный критический путь через этот этап (что означает меньшее количество циклов в секунду). Кроме того, для вычисления цели перехода обычно требовалось 16-битное сложение и 14-битный инкремент. Разрешение ветвления на этапе декодирования позволило получить только штраф за неправильное предсказание ветвления за один цикл. Поскольку ветви очень часто брались (и, следовательно, предсказывались неверно), было очень важно сохранить низкий штраф.

Execute

На этапе Execute происходит фактическое вычисление. Обычно этот каскад состоит из ALU, а также битового шифтера. Он также может включать множитель и делитель нескольких циклов.

ALU отвечает за выполнение логических операций (and, or, not, nand, nor, xor, xnor), а также за выполнение целочисленного сложения и вычитания. Помимо результата, ALU обычно предоставляет биты состояния, например, был ли результат 0 или произошло ли переполнение.

Битовый сдвигатель отвечает за сдвиг и поворот.

Инструкции на этих простых RISC-машинах можно разделить на три класса задержки в зависимости от типа операции:

  • Операция регистр-регистр (задержка за один цикл): сложение, вычитание, сравнение и логические операции. На этапе выполнения два аргумента были переданы простому ALU, который сгенерировал результат к концу этапа выполнения.
  • Ссылка на память (двухцикловая задержка). Все загружается по памяти. На этапе выполнения ALU добавил два аргумента (регистр и постоянное смещение), чтобы создать виртуальный адрес к концу цикла.
  • Многоступенчатые инструкции (Задержка при большом количестве циклов). Целочисленное умножение и деление, а также все операции с плавающей запятой. На этапе выполнения операнды этих операций подавались в многоцикловый блок умножения / деления. Остальная часть конвейера могла продолжить выполнение, пока модуль умножения / деления выполнял свою работу. Чтобы не усложнять этап обратной записи и логику выдачи, команда мультицикла записывала свои результаты в отдельный набор регистров.

Доступ к памяти

Если требуется доступ к памяти данных, это делается на этом этапе.

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

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

Обратная запись

На этом этапе как одиночные, так и двухцикловые инструкции записывают свои результаты в регистровый файл. Обратите внимание, что два разных этапа обращаются к регистровому файлу одновременно - этап декодирования считывает два исходных регистра, в то время как этап обратной записи записывает регистр назначения предыдущей инструкции. Для настоящего кремния это может быть опасно (подробнее об опасностях см. Ниже). Это потому, что один из исходных регистров, считываемых при декодировании, может быть таким же, как регистр назначения, записываемый при обратной записи. Когда это происходит, то одни и те же ячейки памяти в регистровом файле читаются и записываются одновременно. На кремнии многие реализации ячеек памяти не будут работать правильно при одновременном чтении и записи.

Опасности

Хеннесси и Паттерсон придумали термин опасность для ситуаций, когда инструкции в конвейере приводят к неправильным ответам.

Структурные опасности

Структурные опасности возникают, когда две инструкции могут пытаться использовать одни и те же ресурсы в одно и то же время. Классические конвейеры RISC избегали этих опасностей, копируя оборудование. В частности, инструкции перехода могли использовать ALU для вычисления целевого адреса перехода. Если бы ALU использовался для этой цели на этапе декодирования, инструкция ALU, за которой следует ветвление, увидела бы, что обе инструкции попытались использовать ALU одновременно. Этот конфликт легко разрешить, сконструировав специализированный сумматор целевых переходов на этапе декодирования.

Опасности данных

Опасности данных возникают, когда инструкция, составленная вслепую, будет пытаться использовать данные до того, как данные будут доступны в регистровом файле.

В классическом конвейере RISC опасностей данных избегают в одним из двух способов:

Решение A. Обход

Обход также известен как пересылка операндов.

Предположим, ЦП выполняет следующий фрагмент кода:

SUB r3, r4 ->r10; Записывает r3 - r4 в r10 И r10, r3 ->r11; Записывает r10 и r3 в r11

Этапы выборки и декодирования инструкций отправляют вторую инструкцию на один цикл после первой. Они текут по конвейеру, как показано на этой диаграмме:

Pipeline Data Hazard.svg

В простом конвейере, без учета опасностей, опасность данных прогрессирует следующим образом:

В цикле 3 инструкция SUBвычисляет новое значение для r10. В том же цикле декодируется операция И, и значение r10выбирается из файла регистров. Однако инструкция SUBеще не записала свой результат в r10. Обратная запись обычно происходит в цикле 5 (зеленая рамка). Следовательно, значение, прочитанное из регистрового файла и переданное в ALU (на этапе Execute операции AND, красный прямоугольник) неверно.

Вместо этого мы должны передать данные, которые были вычислены с помощью SUB, обратно на этап Execute (то есть в красный кружок на диаграмме) операции ANDперед обычно пишется обратно. Решение этой проблемы - пара байпасных мультиплексоров. Эти мультиплексоры находятся в конце этапа декодирования, и их выходы с флопами являются входами для ALU. Каждый мультиплексор выбирает между:

  1. Порт чтения файла регистров (т.е. выход этапа декодирования, как в наивном конвейере): красная стрелка
  2. Текущий конвейер регистров ALU (для обхода одним этапом): синяя стрелка
  3. Текущий конвейер регистров на этапе доступа (который является либо загруженным значением, либо перенаправленным результатом ALU, это обеспечивает обход двух этапов): фиолетовая стрелка. Обратите внимание, что для этого требуется, чтобы данные были переданы назад во времени на один цикл. В этом случае необходимо вставить кружок , чтобы остановить операцию Идо тех пор, пока данные не будут готовы.

Логика этапа декодирования сравнивает регистры, записанные инструкциями на этапах выполнения и доступа конвейера в регистры, считываемые инструкцией на этапе декодирования, и заставляют мультиплексоры выбирать самые последние данные. Эти обходные мультиплексоры позволяют конвейеру выполнять простые инструкции с задержкой, равной только ALU, мультиплексору и триггеру. Без мультиплексоров задержка записи, а затем чтения файла регистров должна была бы быть включена в задержку этих инструкций.

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

Data Forwarding (One Stage).svg

Решение Б. Блокировка конвейера

Однако следует учитывать следующие инструкции:

LD adr ->r10 AND r10, r3 ->r11

Данные, считанные с адреса adrне присутствует в кэше данных до завершения этапа доступа к памяти инструкции LD. К этому времени инструкция Иуже проходит через АЛУ. Чтобы решить эту проблему, потребовалось бы, чтобы данные из памяти были переданы назад во времени на вход ALU. Это невозможно. Решение состоит в том, чтобы задержать выполнение инструкции Ина один цикл. Опасность данных обнаруживается на этапе декодирования, а этапы выборки и декодирования застопорены - им не разрешается сбрасывать свои входные данные и поэтому они остаются в одном и том же состоянии в течение цикла. На этапах выполнения, доступа и обратной записи ниже по потоку обнаруживается дополнительная инструкция без операции (NOP), вставленная между инструкциями LDи И.

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

Обход назад во времениПроблема решена с помощью пузыря
Data Forwarding (Two Stage, error).svg Data Forwarding (Two Stage).svg

Блокировка конвейера не должна быть однако используется с любой пересылкой данных. Первый пример SUB, за которым следует ANDи второй пример LD, за которым следует AND, могут быть решены путем остановки первого этапа. на три цикла до тех пор, пока не будет достигнута обратная запись и данные в регистровом файлеверны, в результате чего на этапе декодирования ANDбудет выбрано правильное значение регистра. Это приводит к значительному снижению производительности, так как процессор много времени тратит на то, чтобы ничего не обрабатывать, но тактовые частоты можно увеличить, поскольку логика пересылки меньше, чем нужно ждать.

Эту опасность для данных можно довольно легко обнаружить, когда машинный код программы написан компилятором. Машина Stanford MIPS полагалась на компилятор, чтобы добавить инструкции NOP в этом случае, вместо того, чтобы иметь схему для обнаружения и (что более утомительно) остановки первых двух этапов конвейера. Отсюда и название MIPS: микропроцессор без взаимосвязанных этапов конвейера. Оказалось, что дополнительные инструкции NOP, добавленные компилятором, расширили двоичные файлы программы настолько, что снизилась частота попаданий в кэш инструкций. Аппаратное обеспечение, хотя и дорогое, было возвращено в более поздние разработки, чтобы улучшить процент попаданий в кэш команд, после чего аббревиатура перестала иметь смысл.

Опасности управления

Опасности управления вызваны условным и безусловным переходом. Классический конвейер RISC разрешает переходы на этапе декодирования, что означает, что повторение разрешения переходов длится два цикла. Есть три следствия:

  • Повторение разрешения ветвления проходит через довольно много схем: чтение кэша инструкций, чтение файла регистров, вычисление условия ветвления (которое включает 32-битное сравнение на процессорах MIPS) и следующая инструкция мультиплексор адресов.
  • Поскольку цели перехода и перехода вычисляются параллельно чтению регистра, RISC ISA обычно не имеют инструкций, которые переходят на адрес регистр + смещение. Поддерживается переход к регистру.
  • При любом переходе инструкция сразу после перехода всегда выбирается из кэша инструкций. Если эта инструкция игнорируется, существует штраф за один цикл на каждую взятую ветвь IPC, что достаточно велико.

Существует четыре схемы для решения этой проблемы производительности с ветвями:

  • Прогноз не выполнен: Всегда извлекайте инструкцию после перехода из кеша инструкций, но выполняйте ее только в том случае, если ветвление не выполнено. Если ответвление не занято, трубопровод остается заполненным. Если переход выполняется, инструкция сбрасывается (помечается, как если бы она была NOP), и возможность одного цикла завершить инструкцию теряется.
  • Вероятность перехода: всегда получать инструкцию после перехода из инструкции cache, но выполнить его только в том случае, если ветка была взята. Компилятор всегда может заполнить слот задержки ветвления в такой ветке, и, поскольку ветки выполняются чаще, чем нет, такие ветки имеют меньший штраф IPC, чем предыдущий тип.
  • Слот задержки ветвления : всегда получать инструкцию после перехода из кеша инструкций и всегда выполнять его, даже если ветвление выполнено. Вместо того, чтобы взимать штраф IPC за некоторую долю взятых ветвей (возможно, 60%) или неиспользованных (возможно, 40%), слоты задержки ветвления принимают штраф IPC для тех ветвей, в которых компилятор не может запланировать слот задержки ветвления. Разработчики SPARC, MIPS и MC88K разработали слот задержки ветвления в своих ISA.
  • Прогнозирование ветвления : параллельно с выборкой каждой инструкции угадывайте, является ли инструкция переходом или переходом, и если да, угадывайте цель. В цикле после перехода или перехода получить инструкцию в предполагаемой цели. Если предположение неверно, очистите неправильно выбранную цель.

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

Отложенные переходы критиковались как плохой краткосрочный выбор в дизайне ISA:

  • Компиляторы обычно испытывают некоторые трудности с поиском логически независимых инструкций для размещения после перехода (инструкция после перехода называется слотом задержки), поэтому они должны вставлять NOP в слоты задержки.
  • Суперскалярные процессоры, которые выбирают несколько инструкций за цикл и должны иметь некоторую форму предсказания ветвлений, не выигрывают от отложенных ветвей. Alpha ISA не учитывает отложенные переходы, так как он был предназначен для суперскалярных процессоров.
  • Наиболее серьезным недостатком отложенных переходов является дополнительная сложность управления, которую они влекут. Если инструкция слота задержки принимает исключение, процессор должен быть перезапущен на ветви, а не на следующей инструкции. В этом случае исключения имеют по существу два адреса, адрес исключения и адрес перезапуска, и правильное создание и различение этих двух адресов во всех случаях было источником ошибок для более поздних разработок.
Исключения

Предположим, что 32- bit RISC обрабатывает инструкцию ADD, которая складывает два больших числа, и результат не умещается в 32 бита. Что происходит?

Самое простое решение, предоставляемое большинством архитектур, - это арифметика обертывания. У чисел, превышающих максимально возможное закодированное значение, самые старшие биты обрезаются до тех пор, пока они не подходят. В обычной системе счисления 3000000000 + 3000000000 = 6000000000. При беззнаковой 32-битной арифметике обертывания 3000000000 + 3000000000 = 1705032704 (6000000000 mod 2 ^ 32). Это может показаться не очень полезным. Самым большим преимуществом арифметики с оболочкой является то, что каждая операция дает четко определенный результат.

Но программист, особенно если он программирует на языке, поддерживающем большие целые числа (например, Lisp или Scheme ), может не

Последняя правка сделана 2021-05-15 10:17:09
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте