Слот задержки
Эта статья нуждается в дополнительных цитатах для проверки . ( октябрь 2023 г. ) |
В компьютерной архитектуре слот задержки — это слот команд, который выполняется без воздействия предыдущей инструкции. [1] Наиболее распространенной формой является одна произвольная инструкция, расположенная сразу после ветвления инструкции в архитектуре RISC или DSP ; эта инструкция будет выполнена, даже если предыдущая ветвь будет выбрана. Это приводит к тому, что инструкция выполняется не по порядку по сравнению с ее расположением в исходном коде языка ассемблера .
Современные конструкции процессоров обычно не используют слоты задержки, а вместо этого выполняют все более сложные формы предсказания перехода . В этих системах ЦП немедленно переходит к той, которая, по его мнению, будет правильной стороной ветки, и тем самым устраняется необходимость в коде указывать какую-то несвязанную инструкцию, которая не всегда может быть очевидна во время компиляции. Если предположение неверно и необходимо вызвать другую сторону ветки, это может привести к длительной задержке. Это происходит достаточно редко, поэтому ускорение обхода интервала задержки легко компенсируется меньшим количеством неправильных решений.
Конвейерная обработка
[ редактировать ]Центральный процессор обычно выполняет инструкции машинного кода, используя четырехэтапный процесс; инструкция сначала считывается из памяти, затем декодируется, чтобы понять, что необходимо выполнить, затем эти действия выполняются, и, наконец, любые результаты записываются обратно в память. инструкций занимало несколько тактов В ранних разработках каждый из этих этапов выполнялся последовательно, так что выполнение машины. Например, в Zilog Z80 минимальное количество тактов, необходимое для выполнения инструкции, составляло четыре, но для некоторых (редких) инструкций могло достигать 23 тактов. [2]
На любом этапе обработки инструкции задействована только одна часть чипа. Например, на этапе выполнения обычно только арифметико-логический блок активен (АЛУ), в то время как другие блоки, например те, которые взаимодействуют с основной памятью или декодируют инструкцию, простаивают. Одним из способов улучшить общую производительность компьютера является использование конвейера команд . Это добавляет некоторую дополнительную схему для хранения промежуточных состояний инструкции во время ее прохождения через модули. Хотя это не улучшает время цикла какой-либо отдельной инструкции, идея состоит в том, чтобы позволить второй инструкции использовать другие субмодули ЦП, когда предыдущая инструкция перейдет дальше. [3]
Например, пока одна инструкция использует АЛУ, следующая инструкция программы может находиться в декодере, а третья может быть получена из памяти. При такой компоновке типа сборочной линии общее количество инструкций, обрабатываемых в любой момент времени, может быть увеличено на количество стадий конвейера. Например, в Z80 четырехступенчатый конвейер может повысить общую пропускную способность в четыре раза. Однако из-за сложности синхронизации инструкций реализовать это будет непросто. Гораздо более простая архитектура набора команд (ISA) MOS 6502 позволила включить двухэтапный конвейер, что дало ему производительность, примерно вдвое превышающую производительность Z80 на любой заданной тактовой частоте. [4]
Проблемы с ветвлением
[ редактировать ]Основная проблема реализации конвейеров в ранних системах заключалась в том, что количество циклов инструкций сильно различалось. Например, инструкция по добавлению двух значений часто предлагалась в нескольких версиях или кодах операций , которые различались в зависимости от того, где они считываются в данных. Одна из версий add
может взять значение, найденное в одном регистре процессора , и добавить его к значению в другом, другая версия может добавить значение, найденное в памяти, в регистр, а другая может добавить значение из одной ячейки памяти в другую ячейку памяти. Каждая из этих инструкций занимает разное количество байтов для представления ее в памяти, то есть для их выборки требуется разное количество времени, может потребоваться несколько проходов через интерфейс памяти для сбора значений и т. д. Это значительно усложняет логику конвейера. Одной из целей концепции дизайна чипа RISC было исключение этих вариантов, чтобы упростить логику конвейера, что привело к классическому конвейеру RISC , который выполняет одну инструкцию за каждый цикл.
Однако в конвейерных системах возникает одна проблема, которая может снизить производительность. Это происходит, когда следующая инструкция может измениться в зависимости от результатов последней. В большинстве систем это происходит при возникновении ветвления . Например, рассмотрим следующий псевдокод:
top: read a number from memory and store it in a register read another number and store it in a different register add the two numbers into a third register write the result to memory read a number from memory and store it in another register ...
В этом случае программа является линейной и ее можно легко конвейеризировать. Как только первый read
инструкция прочитана и декодируется, вторая read
инструкцию можно прочитать из памяти. Когда первый переходит к исполнению, add
читается из памяти, пока второй read
декодирование и так далее. Хотя для завершения первого этапа по-прежнему требуется то же количество циклов. read
, к моменту завершения значения из второго будут готовы, и ЦП сможет немедленно их добавить. В неконвейерном процессоре выполнение первых четырех инструкций займет 16 тактов, в конвейерном — всего пять.
Теперь рассмотрим, что происходит при добавлении ветки:
top: read a number from memory and store it in a register read another number and store it in a different register add the two numbers into a third register if the result in the 3rd register is greater than 1000, then go back to top: (if it is not) write the result to memory read a number from memory and store it in another register ...
В этом примере результат сравнения в четвертой строке приведет к изменению «следующей инструкции»; иногда это будет следующее write
в памяти, и иногда это будет read
по памяти вверху. Конвейер процессора обычно уже прочитал следующую инструкцию, write
к тому моменту, когда АЛУ рассчитает, какой путь он выберет. Это известно как опасность ветвления . Если ему придется вернуться наверх, write
инструкцию следует отбросить и read
Вместо этого инструкция читается из памяти. Это занимает как минимум один полный цикл инструкции и приводит к тому, что конвейер оказывается пустым хотя бы на время выполнения одной инструкции. Это известно как «застой конвейера» или «пузырь» и, в зависимости от количества ветвей кода, может оказать заметное влияние на общую производительность.
Слоты задержки ответвления
[ редактировать ]Одной из стратегий решения этой проблемы является использование слота задержки , который относится к слоту команд после любой инструкции, для выполнения которой требуется больше времени. В приведенных выше примерах команда, требующая больше времени, представляет собой ветвление, которое на сегодняшний день является наиболее распространенным типом слота задержки, и их чаще называют слотом задержки ветвления .
В ранних реализациях инструкция, следующая за веткой, заполнялась пустой операцией или NOP
, просто для того, чтобы заполнить конвейер, чтобы убедиться, что время выбрано правильно, чтобы к моменту NOP
была загружена из памяти, ветвь была завершена, и счетчик программы мог быть обновлен с использованием правильного значения. Это простое решение тратит имеющееся время обработки. Вместо этого более продвинутые решения будут пытаться идентифицировать другую инструкцию, обычно расположенную поблизости в коде, и поместить ее в слот задержки, чтобы выполнить полезную работу.
В приведенных выше примерах read
инструкция в конце полностью независима, не опирается на какую-либо другую информацию и может быть выполнена в любое время. Это делает его подходящим для размещения в слоте задержки ветвления. Обычно это обрабатывается автоматически программой ассемблера или компилятором , который меняет порядок инструкций:
read a number from memory and store it in a register read another number and store it in a different register add the two numbers into a third register if the result in the 3rd register is greater than 1000, then go back to the top read a number from memory and store it in another register (if it is not) write the result to memory ...
Теперь, когда ветвь выполняется, она продолжает выполнять следующую инструкцию. К тому моменту, когда инструкция считывается в процессор и начинается декодирование, результат сравнения уже готов, и процессор теперь может решить, какую инструкцию читать следующей. read
вверху или write
внизу. Это позволяет избежать потери времени и постоянно поддерживать заполненность конвейера.
Найти инструкцию для заполнения слота может быть сложно. Компиляторы обычно имеют ограниченное «окно» для изучения и могут не найти подходящую инструкцию в этом диапазоне кода. Более того, инструкция не может полагаться ни на какие данные внутри ветки; если add
Инструкция принимает предыдущее вычисление в качестве одного из своих входных данных, этот вход не может быть частью кода в ветви, которая может быть использована. Принятие решения о том, правда ли это, может быть очень сложным при наличии переименования регистров , при котором процессор может помещать данные в регистры, отличные от тех, которые указаны в коде, без ведома компилятора.
Другой побочный эффект заключается в том, что требуется специальная обработка при управлении точками останова в инструкциях, а также при пошаговом выполнении отладки внутри слота задержки ветвления. Прерывание не может произойти во время интервала задержки ветвления и откладывается до окончания интервала задержки ветвления. [5] [6] Размещение инструкции ветвления в слоте задержки ветвления запрещено или устарело. [7] [8] [9]
Идеальное количество слотов задержки ветвления в конкретной реализации конвейера определяется количеством этапов конвейера, наличием пересылки регистров , на каком этапе конвейера вычисляются условия ветвления, ли целевой буфер ветвления используется (BTB) или нет. и многие другие факторы. Требования совместимости программного обеспечения диктуют, что архитектура не может изменять количество слотов задержки от одного поколения к другому. Это неизбежно требует, чтобы новые аппаратные реализации содержали дополнительное оборудование, чтобы гарантировать соблюдение архитектурного поведения, несмотря на то, что оно больше не актуально.
Реализации
[ редактировать ]Слоты задержки перехода встречаются в основном в архитектурах DSP и более старых архитектурах RISC . MIPS , PA-RISC (можно указать ветвь с задержкой или без задержки), [10] ETRAX CRIS , SuperH (инструкции безусловного перехода имеют один слот задержки), [11] Ам29000 , [12] Intel i860 (инструкции безусловного перехода имеют один слот задержки), [13] MC88000 (можно указать ветвь с задержкой или без задержки), [14] и SPARC — это RISC-архитектуры, каждая из которых имеет один слот задержки ветвления; PowerPC , ARM , Alpha , V850 и RISC-V их не имеют. Архитектуры DSP , каждая из которых имеет один слот задержки ветвления, включают μPD77230. [15] и VS DSP . SHARC DSP и MIPS-X используют слот двойной задержки; [16] такой процессор выполнит пару инструкций, следующих за командой перехода, прежде чем переход вступит в силу. Оба TMS320C3x [17] и TMS320C4x [8] используйте слот тройной задержки ветвления. TMS320C4x имеет ветвления как без задержки, так и с задержкой. [8]
В следующем примере показаны отложенные ветки на языке ассемблера для SHARC DSP, включая пару после инструкции RTS. Регистры с R0 по R9 очищаются в ноль в порядке номера (после R6 очищается регистр R7, а не R9). Ни одна инструкция не выполняется более одного раза.
R0 = 0; CALL fn (DB); /* call a function, below at label "fn" */ R1 = 0; /* first delay slot */ R2 = 0; /* second delay slot */ /***** discontinuity here (the CALL takes effect) *****/ R6 = 0; /* the CALL/RTS comes back here, not at "R1 = 0" */ JUMP end (DB); R7 = 0; /* first delay slot */ R8 = 0; /* second delay slot */ /***** discontinuity here (the JUMP takes effect) *****/ /* next 4 instructions are called from above, as function "fn" */ fn: R3 = 0; RTS (DB); /* return to caller, past the caller's delay slots */ R4 = 0; /* first delay slot */ R5 = 0; /* second delay slot */ /***** discontinuity here (the RTS takes effect) *****/ end: R9 = 0;
Слот задержки загрузки
[ редактировать ]Слот задержки загрузки — это инструкция, которая выполняется сразу после загрузки (регистра из памяти), но не видит и не требует ожидания результата загрузки. Слоты задержки загрузки встречаются очень редко, поскольку задержки загрузки на современном оборудовании крайне непредсказуемы. Загрузка может осуществляться из ОЗУ или из кэша и может замедляться из-за конкуренции за ресурсы. Задержки загрузки наблюдались на самых ранних моделях процессоров RISC. MIPS I ISA (реализованный в микропроцессорах R2000 и R3000 ) страдает от этой проблемы.
Следующий пример — ассемблерный код MIPS I, показывающий как слот задержки загрузки, так и слот задержки ветвления.
lw v0,4(v1) # load word from address v1+4 into v0
nop # wasted load delay slot
jr v0 # jump to the address specified by v0
nop # wasted branch delay slot
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ А.Паттерсон, Дэвид; Л. Хеннесси, Джон (1990). Компьютерная архитектура: количественный подход . Издательство Морган Кауфманн. п. 275. ИСБН 1-55860-069-8 .
- ^ «Страница сборки MSX» .
- ^ «CMSC 411, лекция 19, Конвейерная пересылка данных» . Факультет компьютерных наук и электротехники округа Балтимор Университета Мэриленда . Проверено 22 января 2020 г.
- ^ Кокс, Расс (3 января 2011 г.). «MOS 6502 и лучший верстальщик в мире» .
- ^ «Усовершенствованный сигнальный процессор μPD77230» (PDF) . стр. 38(3-39), 70(3-41) . Проверено 17 ноября 2023 г.
- ^ «Руководство пользователя TMS320C4x» (PDF) . п. 75(3-15) . Проверено 2 декабря 2023 г.
- ^ «Усовершенствованный сигнальный процессор μPD77230» (PDF) . п. 191(4-76) . Проверено 28 октября 2023 г.
- ^ Перейти обратно: а б с «Руководство пользователя TMS320C4x» (PDF) . п. 171(7-9) . Проверено 29 октября 2023 г.
- ^ «Руководство пользователя RISC-микропроцессора MC88100» (PDF) . п. 88(3-33) . Проверено 30 декабря 2023 г.
- ^ ДеРоса, Джон А.; Леви, Генри М. «Оценка отраслевых архитектур» . п. 1 . Проверено 27 января 2024 г.
- ^ «Руководство по аппаратному обеспечению SH7020 и SH7021 RISC-движок SuperH™» . п. 42,70 . Проверено 17 декабря 2023 г.
- ^ «Оценка и программирование семейства 29K RISC, третье издание – ПРОЕКТ» (PDF) . п. 54 . Проверено 20 декабря 2023 г.
- ^ «Справочное руководство программиста 64-битного микропроцессора i860™» (PDF) . п. 70(5-11) . Проверено 21 декабря 2023 г.
- ^ «Руководство пользователя RISC-микропроцессора MC88100» (PDF) . п. 81(3-26) . Проверено 21 декабря 2023 г.
- ^ «Усовершенствованный сигнальный процессор μPD77230» (PDF) . п. 191(4-76) . Проверено 5 ноября 2023 г.
- ^ «Набор инструкций MIPS-X и руководство программиста» (PDF) . п. 18 . Проверено 03 декабря 2023 г.
- ^ «Процессор цифровых сигналов с плавающей запятой TMS320C30» (PDF) . ti.com. п. 14 . Проверено 4 ноября 2023 г.
Внешние ссылки
[ редактировать ]- ДеРоза, Дж.А.; Леви, HM (1987). «Оценка архитектур ветвей § 2 Отложенные ветки» . Материалы 14-го ежегодного международного симпозиума по компьютерной архитектуре (ISCA '87) . Ассоциация вычислительной техники. стр. 10–16. дои : 10.1145/30350.30352 . ISBN 978-0-8186-0776-9 . S2CID 1870852 .
- Прабху, Гурпур М. «Схемы прогнозирования ветвей» . Учебное пособие по архитектуре компьютера . Университет штата Айова. Архивировано из оригинала 07 августа 2020 г.