Разработчики архитектуры компьютеров издавна прибегали к методам проектирования, известным под общим названием "совмещение операций", при котором аппаратура компьютера в любой момент времени выполняет одновременно более одной базовой операции. Этот общий метод включает два понятия: параллелизм и конвейеризацию. Хотя у них много общего и их зачастую трудно различать на практике, эти термины отражают два совершенно различных подхода.
При параллелизме совмещение операций достигается путем воспроизведения аппаратной обрабатывающей структуры в нескольких копиях. Высокая производительность достигается за счет одновременной работы всех элементов структур, осуществляющих решение различных частей задачи.
Конвейеризация (или конвейерная обработка) в общем случае основана на разделении подлежащей исполнению функции на более мелкие части, называемые ступенями, и выделении для каждой из них отдельного блока аппаратуры. Так обработку любой машинной команды можно разделить на несколько этапов (несколько ступеней), организовав передачу данных от одного этапа к следующему. При этом конвейерную обработку можно использовать для совмещения этапов выполнения разных команд. Производительность при этом возрастает благодаря тому, что одновременно на различных ступенях конвейера выполняются несколько команд. Конвейерная обработка такого рода широко применяется во всех современных быстродействующих процессорах.
Для иллюстрации основных принципов построения конвейризованных процессоров будем считать, что набор команд процессора включает типичные арифметические и логические операции, операции с плавающей точкой, операции пересылки данных, операции управления потоком команд и системные операции. В арифметических командах используется трехадресный формат, типичный для RISC-процессоров; команды обработки используют регистровую адресацию, а для обращения к памяти используются операции загрузки и записи содержимого регистров в память.
|
Выполнение типичной команды можно разделить на следующие этапы:
- выборка команды - IF (по адресу, заданному счетчиком команд РС, из памяти извлекается команда);
- декодирование команды / выборка операндов из регистров - ID;
- выполнение операции / вычисление исполнительного адреса памяти - EX;
- обращение к памяти - MEM;
- запоминание результата - WB.
Для организации конвейра мы можем разбить выполнение команд на указанные этапы, отведя для выполнения каждого этапа один такт синхронизации, и начинать в каждом такте выполнение новой команды. Естественно, для хранения промежуточных результатов каждого этапа необходимо использовать буферные регистровые станции. Хотя общее время выполнения одной команды в таком конвейере будет составлять пять тактов, в каждом такте аппаратура будет выполнять в совмещенном режиме пять различных команд.
Работу конвейера можно условно представить в виде временной диаграммы (рис.1), на которой изображены выполняемые команды, номера тактов и этапы выполнения команд.
Номер команды | Номер такта | ||||||||
Команда i | IF | ID | EX | MEM | WB | ||||
Команда i+1 | IF | ID | EX | MEM | WB | ||||
Команда i+2 | IF | ID | EX | MEM | WB | ||||
Команда i+3 | IF | ID | EX | MEM | WB | ||||
Команда i+4 | IF | ID | EX | MEM | WB |
Рис. 1. Диаграмма работы простейшего конвейера.
|
Конвейеризация увеличивает пропускную способность процессора (количество команд, завершающихся в единицу времени), но она не сокращает время выполнения отдельной команды. В действительности, она даже несколько увеличивает время выполнения каждой команды из-за накладных расходов, связанных с управлением буферными регистровыми станциями. Однако увеличение пропускной способности означает, что программа будет выполняться быстрее по сравнению с простой неконвейерной схемой.
В качестве примера рассмотрим неконвейерную машину с пятью этапами выполнения операций, которые имеют длительность 50, 50, 60, 50 и 50 нс соответственно (рис.2). Тогда среднее время выполнения команды в неконвейерной машине будет равно 260 нс. Пусть накладные расходы на организацию конвейерной обработки составляют 5 нс. При конвейерной организации длительность такта будет равна длительности самого медленного этапа обработки плюс накладные расходы, т.е. 65 нс. Это время соответствует среднему времени выполнения команды в конвейере.
Конвейеризация эффективна тогда, когда загрузка конвейера близка к полной, скорость подачи новых команд и операндов соответствует максимальной производительности конвейера, а времена обработки на всех этапах конвейра одинаковы.
| |||
| ||||||||||
Команда 2 | ||||||||||
Команда 3 |
Рис. 2. Эффект конвейеризации при выполнении команд: а) неконвейризованное исполнение, б) конвейризованное исполнение.
При реализации конвейерной обработки возникают ситуации, которые препятствуют выполнению очередной команды из потока команд в предназначенном для нее такте. Такие ситуации называются конфликтами. Конфликты снижают реальную производительность конвейера, которая могла бы быть достигнута в идеальном случае. Конфликты в конвейере приводят к необходимости приостановки выполнения команд (pipeline stall). Обычно в простейших конвейерах, если приостанавливается какая-либо команда, то все следующие за ней команды также приостанавливаются. Команды, предшествующие приостановленной, могут продолжать выполняться, но во время приостановки не выбирается ни одна новая команда.
Существуют три класса конфликтов:
1. Структурные конфликты, которые возникают из-за конфликтов по ресурсам, когда аппаратные средства не могут поддерживать все возможные комбинации команд в режиме одновременного выполнения. Например, машина может иметь только один порт записи в регистровый файл, но при определенных обстоятельствах конвейеру может потребоваться выполнить две записи в регистровый файл в одном такте. Когда последовательность команд наталкивается на такой конфликт, конвейер приостанавливает выполнение одной из команд до тех пор, пока не станет доступным требуемое устройство. Структурные конфликты возникают, например, и в машинах, в которых имеется единственный конвейер памяти для команд и данных. В этом случае, когда одна команда содержит обращение к памяти за данными, оно будет конфликтовать с выборкой более поздней команды из памяти.
2. Конфликты по данным возникающие в том случае, когда применение конвейерной обработки может изменить порядок обращений за операндами так, что этот порядок будет отличаться от порядка, который наблюдается при последовательном выполнении команд на неконвейерной машине.
ADD R1,R2,R3 - сложить R2 и R3, результат записать в R1
SUB R4,R1,R5 - из R1 вычесть R5, результат записать в R4
Команда ADD записывает результат в регистр R1, а команда SUB читает это значение. Если не предпринять никаких мер для того, чтобы предотвратить этот конфликт, команда SUB прочитает неправильное значение и попытается его использовать.
Конфликты по данным могут быть устранены на этапе генерации кода компилятором. Многие современные компиляторы используют технику планирования команд для улучшения производительности конвейера.
Например, для оператора А = B + С компилятор скорее всего сгенерирует следующую последовательность команд
Номер команды | Номер такта | ||||||||
LW R1,В | IF | ID | EX | MEM | WB | ||||
LW R2,С | IF | ID | EX | MEM | WB | ||||
ADD R3,R1,R2 | IF | ID | Stall | EX | MEM | WB | |||
SW A,R3 | IF | Stall | ID | EX | MEM | WB |
Рис. 2. Конвейерное выполнение оператора А = В + С
Очевидно, выполнение команды ADD должно быть приостановлено до тех пор, пока не станет доступным поступающий из памяти операнд C.
Для данного простого примера компилятор никак не может улучшить ситуацию, однако в ряде более общих случаев он может реорганизовать последовательность команд так, чтобы избежать приостановок конвейера. Эта техника, называемая планированием загрузки конвейера (pipeline scheduling) или планированием потока команд (instruction scheduling), использовалась начиная с 60-х годов и стала особой областью интереса в 80-х годах, когда конвейерные машины стали более распространенными.
Пусть, например, имеется последовательность операторов: a = b + c; d = e - f;
Если код не оптимизирован, при выполнении каждого из этих операторов возникнет по одному такту приостановки. Но существует вариант переупорядочения команд, когда приостановки конвейера не произойдет.
LW R1, b
LW R2, c
LW R4, e
ADD R3, R1, R2
LW R7, f
SW a, R3
SUB R5, R4, R7
SW d, R5
В общем случае планирование загрузки конвейера компилятором может требовать увеличенного количества регистров.
Кроме того, существуют и аппаратные методы, позволяющие изменить порядок выполнения команд программы так, чтобы минимизировать приостановки конвейера.
3. Конфликты по управлению, которые возникают при конвейеризации команд переходов и других команд, которые изменяют значение счетчика команд.
Когда выполняется команда условного перехода, она может либо изменить, либо не изменить значение счетчика команд. Поскольку это выясняется на завершающих ступенях конвейера, возникает задача: какую из двух возможных последовательностей команд направить в конвейер вслед за командой перехода. В случае неправильного решения результаты обработки команд на начальных ступенях конвейера должны быть сброшены. Таким образом, конфликты по управлению могут вызывать даже большие потери производительности конвейера, чем конфликты по данным. Простейший метод работы с условными переходами заключается в приостановке конвейера как только обнаружена команда условного перехода до тех пор, пока она не достигнет ступени конвейера, которая вычисляет новое значение счетчика команд. Современные процессоры используют разнообразные методы предсказания перехода, при этом вероятность правильного выбора может достигать 95%.