Последовательность выполнения инструкций процессором может быть нарушена

Обновлено: 21.11.2024

Существующая терминология, используемая для описания уязвимостей побочного канала спекулятивного выполнения, в определенных ситуациях может быть неточной. Вновь обнаруженные уязвимости описываются в терминах старых («призрачных», «расплавленных» и т. д.), что может привести к неправильной интерпретации их действия или воздействия. Кроме того, технические термины с разными значениями, такие как «побочный канал» и «скрытый канал», в некоторых случаях применялись взаимозаменяемо. Цель этой статьи — ввести единую терминологию, которая будет лаконичной и недвусмысленной, а также согласовать ее с исследовательским сообществом 1 там, где это имеет смысл. Корпорация Intel планирует использовать термины, изложенные в этой статье, в качестве руководства в будущем; хотя в настоящее время обновлены не все существующие руководства Intel.

Послушайте Скотта Констебла, исследователя безопасности в лаборатории Intel, обсудите программные методы для смягчения аппаратных атак с временным выполнением во время IEEE SecDev 2020.

Каналы

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

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

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

Справочная информация о спекулятивном исполнении

Современные процессоры выполняют инструкции не по порядку для повышения производительности. Эти неупорядоченные процессоры могут «предполагать», что ветвь или загрузка могут использовать значение до того, как процессор подтвердит правильность спекулятивного значения, и выполнение может временно продолжаться с этим спекулятивным значением. Когда ответвление/загрузка разрешены и известно, было ли предположительно использованное значение правильным, возможны два случая:

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

На рис. 1 показан пример такого поведения условного перехода.

Рисунок 1. Пример, иллюстрирующий предположение о переходе: шевроны показывают невременные инструкции; звездочки показывают временные инструкции.

Хотя результаты переходных инструкций не фиксируются в состоянии архитектурной программы, переходные инструкции могут влиять на состояние микроархитектурного процессора. Например, если временная инструкция пытается загрузить данные с адреса, содержимое которого недоступно ни в одном кэше процессора, то соответствующие данные могут быть загружены в кэш процессора. Состояние этого кеша представляет собой случайный канал. Данные из этого канала можно просматривать с помощью таких методов анализа, как Flush+Reload или Prime+Probe, которые измеряют задержки при доступе к кешу.

Атаки временного выполнения

Атака с временным выполнением использует микроархитектурные побочные эффекты временных инструкций, что позволяет злоумышленнику получить доступ к информации, которая обычно запрещена архитектурными механизмами контроля доступа. Чтобы успешно запустить атаку с временным выполнением, злоумышленник должен иметь возможность:

  1. Доступ к секрету жертвы.
  2. Передайте этот секрет по скрытому каналу.
  3. Получите секрет по скрытому каналу.

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

Атаки с временным выполнением можно разделить на категории в зависимости от их влияния на аппаратные функции защиты. Домен аппаратной защиты (называемый в данном контексте просто доменом) состоит из кода и данных в пределах границы защиты, которая определяется аппаратными механизмами управления доступом, такими как уровень привилегий (кольцо), таблицы страниц и ключи защиты. Примеры доменов включают процессы, анклавы Intel® Software Guard Extensions (Intel® SGX), виртуальные машины (ВМ) и код операционной системы (ОС) кольца 0. Домены также могут быть отдельными машинами или устройствами, подключенными через сеть, шину или другой аппаратный интерфейс; содержимое сетевого/шинного трафика составляет законный канал, а другие измеряемые атрибуты передачи (например, задержка) могут создавать случайные каналы.

Атака временного выполнения характеризуется связью между гаджетом раскрытия и доменами жертвы/противника: атака временного выполнения является обходом домена, если гаджет раскрытия находится в домене злоумышленника, междоменной, если гаджет раскрытия находится в домене злоумышленника. домена жертвы или внутри домена, если гаджет раскрытия информации находится в контролируемой злоумышленником изолированной программной среде 4 в домене жертвы. В следующих разделах они описаны более подробно.

Временная атака с обходом домена

Рисунок 2. Структура атаки временного выполнения с обходом домена: обрезанные синие прямоугольники показывают данные; закругленные красные прямоугольники показывают код злоумышленника; стрелки показывают поток данных секрета во время атаки.

При атаке временного выполнения с обходом домена злоумышленник выполняет временные инструкции, которые обходят аппаратные средства контроля доступа, открывая доступ к секрету за пределами домена злоумышленника. Эта последовательность переходных инструкций также должна содержать передатчик, такой как доступ к памяти, который кодирует секрет в состояние кэша ЦП. Невременный код получателя может восстановить секрет, применив метод анализа кеша, такой как Flush+Reload.

В качестве конкретного примера рассмотрим мошенническую загрузку кэша данных (Meltdown). Домен злоумышленника — это приложение кольца 3, а домен жертвы — ядро ​​операционной системы (кольцо 0). Когда злоумышленник пытается получить доступ к памяти ядра, совместно использующей то же виртуальное адресное пространство, временные инструкции могут разрешить чтение и передачу данных ядра до того, как будут разрешены аппаратные проверки разрешений. Другие примеры атак временного выполнения с обходом домена включают выборку микроархитектурных данных (MDS) и сбой терминала L1 (L1TF).

Атака междоменного временного выполнения

Рис. 3. Структура междоменной атаки с временным выполнением: вырезанные синие поля показывают данные; закругленная красная рамка показывает код злоумышленника; полукруглые оранжевые прямоугольники показывают, что злоумышленник манипулирует кодом жертвы; стрелки показывают поток данных секрета во время атаки.

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

Атаки с междоменным временным выполнением, как правило, наиболее сложны для успешного запуска, поскольку злоумышленник не может создать гаджет для раскрытия информации. Нетривиально найти гаджет раскрытия информации в существующей программе-жертве, которая может временно получить доступ и передать секрет до того, как будет раздавлена. Если противник находится в кольце 3, то шум от других процессов может существенно ослабить достоверность скрытого канала. Синхронизация с жертвой (как того требует Prime+Probe) также может оказаться сложной задачей для злоумышленника с кольцом 3.

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

Атака временного выполнения внутри домена

Рис. 4. Структура атаки с временным выполнением внутри домена: вырезанные синие прямоугольники показывают данные; закругленные красные прямоугольники показывают код злоумышленника; стрелки показывают поток данных секрета во время атаки.

Атака с временным выполнением внутри домена позволяет злоумышленнику, находящемуся в песочнице, получить доступ к секрету в том же домене, обходя программные средства контроля доступа. Например, когда программа JavaScript пытается выполнить произвольный доступ к объекту массива, доступ подвергается проверке границ, которая может включать условный переход. Если программа пытается выполнить доступ за пределы границы, но ветвь предсказывает внутренний путь, инструкции доступа и передачи могут временно выполняться до того, как неверно предсказанный путь будет раздавлен. Этот пример представляет собой атаку обхода проверки границ (вариант Spectre 1), применяемую изолированным программным обеспечением против своего домена.

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

Заключение и выводы для разработчиков

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

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

Если уязвимость описана как имеющая междоменное влияние, то для устранения уязвимости могут потребоваться изменения в программном обеспечении, ОС или коде VMM. Эти изменения программного обеспечения могут использовать функции процессора, которые предотвращают спекуляции или изолируют предикторы переходов между режимами. Разработчики также должны учитывать, что междоменные атаки с временным выполнением, как правило, сложнее запустить, чем другие виды атак с временным выполнением. Таким образом, разработчики должны по своему усмотрению принимать решение о том, как смягчить свое программное обеспечение (например, следует ли вставлять LFENCE автоматически или только в местах, определенных как уязвимые для обхода проверки границ).

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

Классификация временного выполнения

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

Междоменное взаимодействие часто устраняется за счет изоляции предикторов или защитных программных методов (например, SLH, LFENCE и т. д.), развернутых у жертвы для предотвращения использования гаджетов.

Очистка машины упорядочения памяти (MO) происходит, когда запрос отслеживания от другого процессора соответствует источнику для операции данных в конвейере. В этой ситуации конвейер очищается до прекращения загрузки и сохранения.

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

Эта проблема также описана здесь

Машина очистки памяти срабатывает всякий раз, когда ядро ​​ЦП обнаруживает «конфликт порядка памяти». По сути, это означает, что некоторые из текущих ожидающих инструкций пытались получить доступ к памяти, которую, как мы только что обнаружили, в это время записывало какое-то другое ядро ​​ЦП. Поскольку эти инструкции по-прежнему помечены как ожидающие, в то время как событие «эта память только что была записана» означает, что какое-то другое ядро ​​успешно завершило запись, ожидающие инструкции — и все, что зависит от их результатов — задним числом являются неверными: когда мы начали выполнять эти инструкции, мы использовали устаревшую версию содержимого памяти. Так что нам нужно бросить всю эту работу и сделать это заново. Это машина чистая.

Но для меня это не имеет смысла, ЦП не нужно повторно выполнять загрузки в очереди загрузки, поскольку нет общего порядка незаблокированных загрузок/сохранений.

Я вижу проблему в том, что загрузки могут быть переупорядочены:

Если бы порядок выполнения был 1 3 2, то сохранение, например, mov [foo], 1 между 3 и 2 вызвало бы

что действительно нарушило бы правила упорядочения памяти.

Но загрузки нельзя переупорядочить вместе с загрузками, так почему же процессоры Intel очищают конвейер, когда запрос отслеживания от другого ядра совпадает с источником любой текущей нагрузки?
Какие ошибочные ситуации предотвращает такое поведение?

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

1 Ответ 1

Хотя модель упорядочения памяти x86 не позволяет глобально наблюдать за загрузками в любой другой тип памяти, кроме WC, вне порядка программы, реализация фактически позволяет загрузкам выполняться не по порядку. Было бы очень дорого откладывать выдачу запроса на загрузку до завершения всех предыдущих загрузок. Рассмотрим следующий пример:

Предположим, что строка x отсутствует в иерархии кеша и должна быть извлечена из памяти. Однако в кэше L1 присутствуют и Y, и Z. Один из способов поддерживать требование порядка загрузки x86 — не выдавать загрузки Y и X до тех пор, пока загрузка X не получит данные. Однако это приведет к остановке всех инструкций, зависящих от Y и Z, что может привести к значительному снижению производительности.

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

  • Загрузка завершена, в то время как предыдущая загрузка в программном порядке все еще ожидает своих данных, и две загрузки относятся к типу памяти, требующему упорядочения.
  • Другое физическое или логическое ядро ​​изменило строку, прочитанную более поздней загрузкой, и это изменение было обнаружено логическим ядром, выдавшим загрузки, до того, как предыдущая загрузка получила свои данные.

При возникновении обоих этих условий логическое ядро ​​обнаруживает нарушение порядка памяти. Рассмотрим следующий пример:

Предположим, что начальное состояние:

  • [X] = [Y] = 0.
  • Кэш-строка, содержащая Y, уже присутствует в L1D ядра core1. Но X отсутствует в приватных кешах core1.
  • Линия X присутствует в L1D core2 в модифицируемом состоянии когерентности, а линия Y присутствует в L1D core2 в совместно используемом состоянии.

В соответствии с моделью строгого упорядочения x86 единственными допустимыми исходами являются 0, 1 и 3. В частности, исход 2 недопустим.

Может произойти следующая последовательность событий:

  • Core2 выдает запросы предложений для обеих линий. RFO для строки X завершится быстро, но RFO для строки Y должен будет пройти весь путь до L3, чтобы аннулировать строку в частных кешах core1. Обратите внимание, что core2 может фиксировать сохранения только по порядку, поэтому сохранение в строке X ожидает фиксации сохранения в строке Y.
  • Core1 отправляет две загрузки на L1D. Загрузка из строки Y завершается быстро, но для загрузки из X требуется получить строку из приватных кэшей core2. Обратите внимание, что значение Y в этой точке равно нулю.
  • Строка Y удаляется из приватных кэшей ядра1, и ее состояние в ядре2 изменяется на изменяемое состояние согласованности.
  • Core2 теперь фиксирует оба хранилища по порядку.
  • Линия X перенаправляется с ядра 2 на ядро ​​1.
  • Core1 загружает из строки кэша X значение, хранящееся в core2, равное 2.
  • Core1 выводит сумму X и Y, которая равна 0 + 2 = 2. Это недопустимый результат. По сути, core1 загрузил устаревшее значение Y.

Чтобы поддерживать порядок загрузки, буфер загрузки core1 должен отслеживать все недействительные строки, находящиеся в его частных кешах. Когда он обнаруживает, что строка Y была признана недействительной, в то время как есть ожидающие загрузки, которые предшествуют завершенной загрузке из недействительной строки в программном порядке, происходит нарушение порядка памяти, и загрузка должна быть выполнена повторно, после чего она получает самое последнее значение. Обратите внимание, что если строка Y была удалена из приватных кешей core1 до того, как она станет недействительной, и до того, как загрузка из X завершится, возможно, он не сможет отследить аннулирование строки Y в первую очередь. Поэтому необходим механизм для решения этой ситуации.

Если core1 никогда не использует одно или оба загруженных значения, может произойти нарушение порядка загрузки, но оно никогда не будет наблюдаться.Точно так же, если значения, сохраненные core2 в строках X и Y, одинаковы, может произойти нарушение порядка загрузки, но это невозможно наблюдать. Однако даже в этих случаях ядро ​​​​1 по-прежнему без необходимости повторно выдает нарушающую загрузку и воспроизводит все свои зависимости.

Выполнение инструкции происходит в несколько этапов. В разных архитектурах реализовано разное количество этапов, но большинство из них реализуют этапы выполнения команды Fetch, Decode, Execute и WriteBack в четыре или более дискретных этапа. При обсуждении выполнения инструкций мы сосредоточимся на этих четырех этапах выполнения и в качестве примера используем инструкцию ADD. Наш пример инструкции ADD закодирован, как показано на рисунке 1.

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

Чтобы выполнить инструкцию, ЦП сначала выбирает следующую инструкцию из памяти в специальный регистр, регистр инструкций (IR). Адрес памяти инструкции для выборки хранится в другом специальном регистре, программном счетчике (ПК). ПК отслеживает адрес памяти следующей инструкции для выборки и увеличивается как часть выполнения этапа выборки, так что он сохраняет значение адреса памяти самой следующей инструкции. Например, если все инструкции имеют длину 32 бита, то значение ПК увеличивается на 4 (каждый байт, 8 бит, имеет уникальный адрес), чтобы сохранить адрес памяти инструкции, следующей сразу за той, которая была выбрана. Арифметические схемы, которые отделены от АЛУ, увеличивают значение ПК. Значение ПК также может измениться на этапе обратной записи. Например, некоторые инструкции переходят на определенные адреса, связанные, например, с выполнением циклов, if-else или вызовами функций. На рис. 2 показан этап выполнения выборки.

Рисунок 2. Стадия выборки выполнения инструкции: инструкция по адресу памяти, хранящемуся в регистре ПК, считывается из памяти и сохраняется в IR. Значение ПК также увеличивается в конце этого этапа (если инструкции имеют длину 4 байта, то следующий адрес — 1238; фактический размер инструкции зависит от архитектуры и типа инструкции).

После выборки инструкции ЦП декодирует биты инструкции, хранящиеся в регистре IR, на четыре части: старшие биты инструкции кодируют код операции, который определяет операцию, которую необходимо выполнить (например, ADD, SUB, OR, …​), а оставшиеся биты разделены на три подмножества, которые определяют два источника операндов и назначение результата. В нашем примере мы используем регистры как для источника, так и для назначения результата. Код операции отправляется по проводам, которые вводятся в АЛУ, а исходные биты отправляются по проводам, которые являются входами в файл регистров. Исходные биты отправляются на два входа выбора чтения (Sr0 и Sr1), которые определяют, какие значения регистров считываются из файла регистров. Этап декодирования показан на рис. 3.

Рисунок 3. Этап декодирования выполнения инструкции: разделите биты инструкции в IR на компоненты и отправьте их в качестве входных данных в ALU и регистровый файл. Биты кода операции в IR отправляются на вход выбора ALU, чтобы выбрать, какую операцию выполнять. Два набора битов операндов в IR отправляются на входы выбора файла регистров, чтобы выбрать регистры, из которых считываются значения операндов. Биты назначения в IR отправляются в регистровый файл на стадии WriteBack. Они указывают регистр, в который записывается результат АЛУ.

После того, как этап декодирования определяет операцию для выполнения и источники операндов, АЛУ выполняет операцию на следующем этапе, этапе Выполнение. Входные данные АЛУ поступают с двух выходов регистрового файла, а входные данные выбора поступают из битов кода операции инструкции. Эти входные данные проходят через АЛУ для получения результата, объединяющего значения операнда с операцией. В нашем примере АЛУ выводит результат добавления значения, хранящегося в Reg1, к значению, хранящемуся в Reg3, и выводит значения кода условия, связанные с результирующим значением. Этап выполнения показан на рис. 4.

Рисунок 4. Стадия Execution выполнения инструкции: ALU выполняет указанную операцию (из битов кода операции инструкции) над своими входными значениями (из выходных данных регистрового файла).

На этапе WriteBack результат ALU сохраняется в регистре назначения. Файл регистров получает вывод результата АЛУ на входе данных, регистр назначения (из битов инструкций в IR) на входе выбора записи (Sw) и 1 на входе WE. Например, если регистр назначения — Reg0, то биты, кодирующие Reg0 в IR, отправляются в качестве входных данных Sw в файл регистров для выбора регистра назначения. Выходные данные АЛУ отправляются в качестве входных данных в файл регистров, а бит WE устанавливается в 1, чтобы разрешить запись результата АЛУ в регистр Reg0. Этап WriteBack показан на рис. 5.

Рисунок 5. Стадия WriteBack выполнения инструкции: результат стадии выполнения (выход из ALU) записывается в регистр назначения в регистровом файле. Выход ALU представляет собой данные файла регистров на входе, биты назначения инструкции поступают на вход выбора записи файла регистров (Sw), а вход WE устанавливается в 1, чтобы разрешить запись Данные в значении для указанного целевого регистра.

5.6.1. Исполнение по часам

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

Часы ЦП измеряют дискретное время, а не непрерывное. Другими словами, существует время 0, за которым следует время 1, за которым следует время 2, и так далее для каждого последующего такта часов. Время тактового цикла процессора измеряет время между каждым тактом. Тактовая частота процессора (или тактовая частота) равна 1/(время тактового цикла). Обычно он измеряется в мегагерцах (МГц) или гигагерцах (ГГц). Тактовая частота 1 МГц соответствует одному миллиону тактов в секунду, а 1 ГГц — одному миллиарду тактов в секунду. Тактовая частота является мерой того, насколько быстро может работать ЦП, и является оценкой максимального количества инструкций в секунду, которые может выполнять ЦП. Например, на простых скалярных процессорах, таких как ЦП в нашем примере, процессор с частотой 2 ГГц может обеспечить максимальную скорость выполнения инструкций в два миллиарда инструкций в секунду (или две инструкции в наносекунду).

Хотя увеличение тактовой частоты на одном компьютере повысит его производительность, сама по себе тактовая частота не является значимым показателем для сравнения производительности различных процессоров. Например, некоторые архитектуры (например, RISC) требуют меньше этапов для выполнения инструкций, чем другие (например, CISC). В архитектурах с меньшим количеством стадий выполнения более медленные часы могут давать такое же количество инструкций, выполняемых в секунду, как и в другой архитектуре с более высокой тактовой частотой, но большим количеством стадий выполнения. Однако для конкретного микропроцессора удвоение его тактовой частоты примерно удвоит скорость выполнения инструкций.

Исторически сложилось так, что увеличение тактовой частоты (наряду с разработкой более сложных и мощных микроархитектур, которые могут управляться более быстрыми тактовыми частотами) было для компьютерных архитекторов очень эффективным способом повышения производительности процессора. Например, в 1974 году процессор Intel 8080 работал на частоте 2 МГц (тактовая частота два миллиона циклов в секунду). Тактовая частота Intel Pentium Pro, представленного в 1995 году, составляла 150 МГц (150 миллионов циклов в секунду), а тактовая частота Intel Pentium 4, представленного в 2000 году, составляла 1,3 ГГц или (1,3 миллиарда циклов в секунду). Пик тактовой частоты пришелся на середину-конец 2000-х годов, когда процессоры, такие как IBM z10, имели тактовую частоту 4,4 ГГц.

Однако сегодня тактовая частота ЦП достигла своего предела из-за проблем, связанных с отводом тепла более быстрыми тактовыми частотами. Этот предел известен как стена мощности. Стена питания привела к разработке многоядерных процессоров, начиная с середины 2000-х годов. Многоядерные процессоры имеют несколько «простых» ядер ЦП на чип, каждое ядро ​​​​приводится в действие тактовой частотой, частота которой не увеличилась по сравнению с ядром предыдущего поколения. Многоядерный процессор — это способ повысить производительность ЦП без увеличения его тактовой частоты.

Схема часов

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

Рисунок 6. Обычный шаблон вывода 1 и 0 тактовой схемы. Каждая последовательность 1 и 0 составляет тактовый цикл.

Тактовый цикл (или тик) — это подпоследовательность 1 и 0 из шаблона схемы синхронизации. Переход от 1 к 0 или от 0 к 1 называется фронтом синхронизации. Тактовые фронты запускают изменения состояния в схемах ЦП, управляя выполнением инструкций. Нарастающий фронт тактового сигнала (переход от 0 к 1 в начале нового тактового цикла) указывает на состояние, в котором входные значения готовы к этапу выполнения инструкции. Например, передний фронт сигнализирует о том, что входные значения в схему АЛУ готовы. Пока значение часов равно 1, эти входы распространяются по схеме до тех пор, пока выход схемы не будет готов. Это называется задержкой распространения по цепи. Например, пока тактовый сигнал равен 1, входные значения в АЛУ распространяются по рабочим схемам АЛУ, а затем через мультиплексор для получения корректных выходных данных АЛУ для операции объединения входных значений. На заднем фронте (переход от 1 к 0) выходы каскада стабильны и готовы к передаче в следующее место (показано как «выход готов» на рисунке 7). Например, выход из АЛУ готов по заднему фронту. Пока значение часов равно 0, выходные данные АЛУ распространяются на входные данные регистрового файла. В следующем тактовом цикле нарастающий фронт указывает, что входное значение регистрового файла готово для записи в регистр (показано как «новый ввод» на рис. 7).

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

Длительность тактового цикла (или тактовая частота) ограничена максимальной задержкой распространения на любом этапе выполнения инструкции. Стадия выполнения и распространение через ALU обычно является самой продолжительной стадией. Таким образом, половина времени тактового цикла должна быть не быстрее, чем время распространения входных значений АЛУ по самой медленной рабочей схеме к выходам АЛУ (другими словами, выходы отражают результаты работы на входах) . Например, в нашем ALU с четырьмя операциями (OR, ADD, AND и EQUALS) сумматор с неравномерным переносом имеет наибольшую задержку распространения и определяет минимальную продолжительность тактового цикла.

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

Если, например, тактовая частота составляет 1 ГГц, выполнение одной инструкции занимает 4 наносекунды (каждый из четырех этапов занимает 1 наносекунду). При тактовой частоте 2 ГГц выполнение одной инструкции занимает всего 2 наносекунды.

Хотя тактовая частота является фактором производительности процессора, сама по себе тактовая частота не является значимым показателем его производительности. Вместо этого среднее количество циклов на инструкцию (CPI), измеренное при полном выполнении программы, является лучшим показателем производительности процессора. Как правило, процессор не может поддерживать свой максимальный CPI для выполнения всей программы. Субмаксимальный CPI является результатом многих факторов, в том числе выполнения общих программных конструкций, которые изменяют поток управления, таких как циклы, ветвление if-else и вызовы функций. Средний показатель CPI для запуска набора стандартных тестовых программ используется для сравнения различных архитектур. CPI является более точным показателем производительности ЦП, поскольку он измеряет его скорость выполнения программы по сравнению с показателем одного аспекта выполнения отдельной инструкции. Дополнительную информацию о производительности процессора и проектировании процессоров для повышения их производительности см. в учебнике по компьютерной архитектуре 1.

5.6.2. Собираем все вместе: центральный процессор в полноценном компьютере

Путь данных (ALU, регистровый файл и шины, которые их соединяют) и путь управления (схема выполнения инструкций) составляют ЦП.Вместе они реализуют части обработки и управления архитектуры фон Неймана. Современные процессоры реализованы в виде цифровых схем, встроенных в кремниевые чипы. Микросхема процессора также включает в себя некоторую быструю встроенную кэш-память (реализованную с помощью схем хранения с защелкой), используемую для хранения копий недавно использованных программных данных и инструкций рядом с процессором. Дополнительную информацию о встроенной кэш-памяти см. в главе «Хранилище и иерархия памяти».

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

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

5.6.3. Сноски

Авторское право (C) 2020 Dive into Systems, LLC.

Dive into Systems находится под лицензией Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0).

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

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

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

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

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

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

Другой альтернативой является строгая согласованность памяти, при которой доступ к памяти происходит строго в порядке программы. Строгая согласованность памяти запрещает любое изменение порядка загрузки/сохранения.

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

Это модели согласованности WW, WS, SW и SS, где первый символ указывает на тип согласованности процессора (слабая/сильная), а второй тип согласованности памяти (слабая/сильная).

Читайте также: