# Лекция 12. Методы повышения производительности

## Содержание

- [Лекция 12. Методы повышения производительности](#лекция-12-методы-повышения-производительности)
  - [Содержание](#содержание)
  - [Суперскалярный процессор](#суперскалярный-процессор)
    - [Внеочередное выполнение команд](#внеочередное-выполнение-команд)
    - [Переименование регистров](#переименование-регистров)
    - [Переупорядочивание команд](#переупорядочивание-команд)
    - [Централизованное окно команд](#централизованное-окно-команд)
    - [Распределенное окно команд (алгоритм Томасуло)](#распределенное-окно-команд-алгоритм-томасуло)
    - [Восстановление последовательности](#восстановление-последовательности)
  - [Параллелизм](#параллелизм)
  - [Многопоточность](#многопоточность)
  - [Пакованная арифметика](#пакованная-арифметика)
  - [Классификация Флинна](#классификация-флинна)
    - [Основные материалы лекции](#основные-материалы-лекции)

В последних лекциях разрабатывалось три микроархитектуры:

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

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

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

## Суперскалярный процессор

![../.pic/Lectures/12.%20Productivity%20techniques/fig_01.png](../.pic/Lectures/12.%20Productivity%20techniques/fig_01.png)

Обычный, **скалярный процессор** - процессор который работает с одной порцией данных за одну инструкцию.

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

Помимо суперскалярных процессоров существуют еще и **Векторные процессоры** - за раз выполняющие одну инструкцию, но ее операндами выступают упорядоченные массивы данных - векторы.

Пример:

При максимальной загрузке двухканального суперскалярного процессора и идеальной пропускной способности параметр cpi = 0.5 (cycle per instruction) или ipc = 2 (instruction per cycle). Но на практике идеальных суперскалярных процессоров не бывает.

Поэтому для увеличения загрузки суперскалярного процессора применяются **различные подходы**.

### Внеочередное выполнение команд

Внеочередное исполнение описывает исполнение машинных инструкций не в порядке поступления, а по мере готовности к их выполнению. Упрощенно говоря, при внеочередном исполнении, процессор помещает поступающие команды в очередь по порядку и начинает ожидать выполнения всех условий, для обработки этих команд.
Внеочередное выполнение тем эффективнее, чем длиннее конвейер процессора, и чем больше разница между скоростью работы памяти (оперативной или кэшем) и скоростью работы процессора.
В современных компьютерах процессоры работают намного быстрее памяти, поэтому во время ожидания поступления данных процессор может выполнить множество инструкций, операнды которых доступны.
Проблема: при неупорядоченном исполнении в регистрах могут быть
“устаревшие” или “опережающие” значения (конфликты WAW/WAR).

### Переименование регистров

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

### Переупорядочивание команд

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

- **Централизованное окно команд**
- **Распределенное окно команд** (алгоритм Томасуло)

### Централизованное окно команд

![../.pic/Lectures/12.%20Productivity%20techniques/fig_02.png](../.pic/Lectures/12.%20Productivity%20techniques/fig_02.png)

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

![../.pic/Lectures/12.%20Productivity%20techniques/fig_03.png](../.pic/Lectures/12.%20Productivity%20techniques/fig_03.png)

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

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

### Распределенное окно команд (алгоритм Томасуло)

![../.pic/Lectures/12.%20Productivity%20techniques/fig_04.png](../.pic/Lectures/12.%20Productivity%20techniques/fig_04.png)

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

### Восстановление последовательности

![../.pic/Lectures/12.%20Productivity%20techniques/fig_05.png](../.pic/Lectures/12.%20Productivity%20techniques/fig_05.png)

**Буфер восстановления последовательности** (БВП) — это универсальный инструмент для поддержания правильной последовательности исполнения команд в случае нескольких параллельно работающих функциональных блоков.

БВП представляет собой кольцевой буфер с указателями головной и хвостовой части. Указатель головной части содержит адрес, следующего свободного входа. Команды заносятся в БВП в порядке, определяемом программой. Каждая выданная команда помещается в следующую свободную ячейку буфера (говорят, что команде выделен очередной свободным вход БВП.), причем выделение ячеек идет с соблюдением последовательности выдачи команд. Каждый занятый вход содержит также информацию о состоянии хранимой в нем команды: команда только выдана (i), находится в стадии исполнения (х) или уже завершена (f). Указатель хвостовой части показывает па команду, подлежащую удалению из БВП прежде других. Удаление команды разрешено, только если она завершена и предшествующие ей команды уже удалены из буфера. Этот механизм гарантирует что команды покидают БВП строго по порядку. Очередность выполнения команд программы сохраняется благодаря тому, что заносить свои результаты в память или регистры разрешается лишь тем командам, которые покинули БВП.

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

## Параллелизм

Рассмотрим виды параллелизма:

- Временной
- Пространственный

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

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

Не стоит путать и следующие два вида параллелизма:

- Instruction Level Parallelism (ILP) - параллелизм уровня команд (рассмотрен в суперскалярном процессоре)
- Thread Level Parallelism (TLP) - параллелизм уровня потоков (когда две программы работают параллельно, используя разные потоки)

Следует понимать, что суперскалярный процессор повышает производительность тем, что выполняет параллельно несколько инструкций одной программы, то есть обладает _параллелизмом уровня команд_ (ILP).
А многоядерный процессор - тем, что выполняет независимо два (или более) потока инструкций, то есть обладает _параллелизмом уровня потоков_ (TLP).

## Многопоточность

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

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

Важно учесть, что **многопоточность не повышает параллелизм уровня команд (ILP)**, но повышает пропускную способность конвейера.

## Пакованная арифметика

![../.pic/Lectures/12.%20Productivity%20techniques/fig_06.png](../.pic/Lectures/12.%20Productivity%20techniques/fig_06.png)

**Пакованная арифметика** - способ выполнения нескольких однотипных операции за одну инструкцию за счет "склеивания" нескольких чисел. Пример: на 32 битном АЛУ при помощи пакованной арифметики можно произвести сложение 4-х пар 8-битных чисел за одну операцию, вместо того чтобы производить 4 сложения.

## Классификация Флинна

**Классификация Флинна** — общая классификация архитектур ЭВМ по признакам наличия параллелизма в потоках команд и данных. Была предложена Майклом Флинном в 1966 году и расширена в 1972 году.

В ней машины разделяют на группы:

- SISD (single instruction single data)
- SIMD (single instruction multiple data) - Векторные процессоры
- MISD (multiple instruction single data)
- MIMD (multiple instruction multiple data)

### Основные материалы лекции

1. [Ссылка](https://www.youtube.com/watch?v=deTK5ZjFWaw) на видеозапись лекции
