Повышение производительности процессора

Атака в лоб: повышение тактовой частоты

Физическое устройство процессора и памяти таково, что любые действия могут происходить не быстрее, чем с определённой частотой, задаваемой специальным генератором (в виде всплесков напряжения с данной частотой или ещё как-то, неважно). Частота «500 мегагерц» означает полмиллиарда колебаний генератора в секунду, соответственно один такт, за который хоть что-то может выполниться, составляет одну полумиллиардную долю секунды.

При этом

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

Кроме того

Одновременное выполнение инструкций

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

Зависимость по данным: Если в одной операции используется результат работы другой, первая должна выполняться строго после второй.

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

Обратим внимание: разные случаи зависимости если и можно обойти, то по-разному

Масштабирование

Об увеличении количества процессоров (или вычислительных ядер) в ЭВМ см. последующие лекции. Здесь поговорим о масштабировании элементов внутри одного процессора.

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

Векторные операции — выполнение однотипных действий над несколькими элементами данных одновременно.

Суперскалярные вычисления — одновременное выполнение нескольких инструкций и/или миркопрограммных инструкций

Проблема эффективной загрузки

Конвейер

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

Однако это требует особой аппаратной организации и не исключает ситуации неэффективной загрузки конвейера

Пример: такт работы модельной машины

  1. Чтение в РК команды из памяти по адресу, находящемуся в СК
  2. Интерпретация команды в РК (для УМ3 это просто)
  3. Чтение операндов из памяти (от 0 до 2)
  4. Вычисление результата (если необходимо)
  5. Запись результата в память (от 0 до 1)
  6. Вычисление адреса следующей команды в СК

Независимые группы: 1, 2-3, 4, 5-6 можно представить в виде конвейера

  1. Чтение из памяти команд
  2. Декодирование команды и чтение из памяти данных (адреса находятся в известных местах прочтённой команды, поэтому их выделение делается мгновенно)
  3. Вычисление
  4. Запись результата в память и вычисление следующего адреса (зависит от предыдущей стадии, например, при условном переходе)

При идеальной загрузке конвейера в течение одного такта:

  1. N+3-я команда только считывается из памяти
  2. N+4-я команда декодируется и параллельно считываются из памяти операнды
  3. N+1-я команда вычисляется
  4. N-я команда записывает результат в память, и параллельно вычисляется адрес … N+1-й команды :(

=> В случае зависимости по управлению наш примитивный конвейер полностью неэффективен, т. к. последняя стадия N-й команды следует строго перед первой стадией N+1-й!

Однако если команда не предполагает зависимости по управлению, вычисление следующего адреса можно объединить непосредственно с 1-й стадией!

Современные процессоры intel/AMD, по слухам, на микропрограммном конвейерном RISC-ядре, а доступные программисту CISC-инструкции преобразуются в них путём применения всего вышеперечисленного, включая чёрную магию.

Конвейер MIPS

Подробное описание в книге «Цифровая схемотехника и архитектура компьютера» (глава 7.5 КОНВЕЙЕРНЫЙ ПРОЦЕССОР, стр 1007). Можно почитать весь раздел 7.

Вот несколько упрощённая схема узлов процессора MIPS

Замечания:

Pipeline.png

  1. Instruction fetch — выборка команды из кеша команд

  2. Instruction Decode — декодирование команды

    • Операнды выбираются из регистрового блока.
    • Операнды передаются в обход регистрового блока со стадий E, M и W.
    • ALU определяет, выполняется ли условие перехода и вычисляет адрес перехода для команд перехода.
    • Осуществляется преобразование виртуального адреса в физический.

    • Производится поиск адреса команды по TLB и вырабатывается признак hit/miss.

    • Командная логика выбирает адрес команды.
  3. Execution — исполнение

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

    • Производится поиск данных по TLB и вырабатывается признак hit/miss.

    • Все операции умножения и деления выполняются на этой стадии.
  4. Memory fetch — выборка из памяти данных и выравнивание в границах слова

  5. Writeback — «обратная» запись в регистр результата инструкции типа регистр-регистр или загрузки из памяти; обновление регистрового блока

Пример:

   1 lui   $at, 0x1001      # это раскрытие псевдоинстркуции lw $t2, 0x10010000
   2 lw    $t2, 0($at)
   3 sll   $t3, $t3, 2
   4 add   $t2, $t2, $t3
   5 lui   $at, 0x1004      # это раскрытие псевдоинстркуции sw $t2, 0x10040000
   6 sw    $t2, 0($at)

Пример: упрощённый HTML-эмулятор MIPS с конвейером (код на GitHub)

Конфликты конвейера

Конфликты по данным

Конфликт по управлению

Оказывается, проект WebMIPS свободный (?), по крайне мере, он доступен в исходниках. Написан он на ASP.NET, но можно попробовать затолкать :)

Д/З

TODO

LecturesCMC/ArchitectureAssembler2019/10_PipelineScale (последним исправлял пользователь FrBrGeorge 2019-05-17 15:30:18)