Внеочередное исполнение против спекулятивного исполнения
Я прочитал страницу в Википедии о неработающем исполнении и спекулятивных махинациях.
Что я не могу понять, хотя это сходства и различия. Мне кажется, что спекулятивное выполнение использует внеочередное выполнение, когда оно, например, не определило значение условия.
Путаница возникла, когда я прочитал газеты Meltdown и Spectre и провел дополнительное исследование. В документе Meltdown говорится, что Meltdown основан на неупорядоченном исполнении, в то время как некоторые другие ресурсы, включая вики-страницу о состоянии спекулятивного исполнения, Meltdown основаны на спекулятивном исполнении.
Я хотел бы получить некоторые разъяснения по этому поводу.
2 ответа
Добро пожаловать в болото
Вы найдете много статей, которые рассматривают спекулятивное выполнение как своего рода неупорядоченное выполнение (также известное как динамическое выполнение или динамическое планирование). Я мог бы найти это среди лучших результатов поиска:
Спекулятивное исполнение - это метод, используемый разработчиками ЦП для повышения производительности ЦП. Это один из трех компонентов неупорядоченного исполнения, также известного как динамическое выполнение. Наряду с прогнозированием нескольких ветвей (используется для прогнозирования инструкций, которые, скорее всего, понадобятся в ближайшем будущем) и анализом потока данных (используется для выравнивания инструкций для оптимального выполнения, а не для их выполнения в порядке их поступления), спекулятивное выполнение обеспечило значительное улучшение производительности по сравнению с предыдущими процессорами Intel.
Это не точно.
Историческая перспектива
Есть много патентов, которые были поданы и / или выданы в 60-х и 70-х годах на предсказание ветвлений и подобные спекулятивные методы. Я заметил, что все они предполагали конвейерное выполнение, но ни одно из них не требует выполнения вне очереди (большинство даже не упоминают об этом). Пройдя пару минут поиска, я смог найти:
Цифровой компьютер, работающий на высокой скорости, 1966 г.
Блок обработки инструкций для программных отделений, 1966.
Прогнозная система обнаружения ветвей, 1968.
Аппарат обработки данных, 1968 г. (обратите внимание на это).
Компьютер отраслевого прогнозирования, 1981
Таблица истории декодирования для инструкций условного перехода, 1982.
Связь между терминами в соответствии с патентной классификацией США
Согласно патентной классификации США номер класса G06F9/38 относится к "параллельному выполнению команды". Это включает в себя конвейерную обработку, динамическое выполнение, умозрительное выполнение и все, что-либо подобное этому. Номер подкласса G06F9/3836 относится к "выдаче инструкций". Это конкретно параллельные методы планирования команд, такие как выполнение вне очереди. Номер подкласса G06F9/3842, который является родственным G06F9/3836, относится к умозрительному выполнению инструкций. Следовательно, согласно этой классификации, они ортогональны. Учитывая, что патенты США опираются на очень серьезную правовую систему, я думаю, что могу сказать, что их классификация очень точна и сделана очень тщательно.
обсуждение
Спекулятивное исполнение и исполнение вне очереди являются ортогональными. Можно было бы спроектировать процессор в этом OoO, но не умозрительный или умозрительный, а по порядку Я объясню как. Выполнение OoO - это модель выполнения, в которой инструкции могут выполняться в порядке, который потенциально отличается от порядка программы. Тем не менее, инструкции по-прежнему удалены в программном порядке, поэтому наблюдаемое поведение программы совпадает с интуитивно ожидаемым программистом. (Хотя, технически говоря, возможно спроектировать процессор OoO, который выводит команды в неестественном порядке с определенными ограничениями).
Спекулятивное выполнение - это модель выполнения, в которой инструкции могут войти в конвейер и даже начать выполнение, даже не зная точно, что они действительно должны будут выполняться (согласно потоку управления программы). В более широком определении спекулятивного выполнения процессору разрешено спекулировать на чем-либо действительно, включая операнды и области памяти, используемые и доступные инструкцией.
В документе "Расплавление" эти термины определены на странице 3:
В этой статье мы ссылаемся на умозрительное выполнение в более ограниченном смысле, где оно относится к последовательности команд, следующей за веткой, и используем термин выполнение вне порядка, чтобы ссылаться на любой способ получения операции, выполняемой до того, как процессор имеет совершил результаты всех предыдущих инструкций.
Обратите внимание, что инструкции могут быть выполнены умозрительно, но в порядке. Когда этап декодирования конвейера идентифицирует команду условного перехода, он может спекулировать на ветви и ее цели и извлекать инструкции из предсказанного целевого местоположения. Но все же, инструкции также могут быть выполнены по порядку. Однако обратите внимание, что как только предполагаемая инструкция условного перехода и инструкции, извлеченные из прогнозируемого пути (или обоих путей), достигнут стадии проблемы, ни одна из них не будет выполнена, пока все более ранние инструкции не будут отменены. Когда это произойдет, процессор будет знать, был ли прогноз верен, и в противном случае очистить конвейер.
Процессоры, предназначенные для выполнения простых задач и используемые во встроенных системах или устройствах IoT, обычно не являются ни спекулятивными, ни OoO. Настольные и серверные процессоры являются спекулятивными и OoO В середине вычислительного спектра (мобильные телефоны и микроконтроллеры) вы можете найти процессоры, которые являются OoO, но не умозрительные (такие как ARM Cortex-A9). Некоторые процессоры Intel Atom являются умозрительными, но по порядку. Спекулятивное исполнение особенно выгодно при использовании с OoO.
Путаница возникла, когда я прочитал газеты Meltdown и Spectre и провел дополнительное исследование. В документе Meltdown говорится, что Meltdown основан на неупорядоченном исполнении, в то время как некоторые другие ресурсы, включая вики-страницу о состоянии спекулятивного исполнения, Meltdown основаны на спекулятивном исполнении.
Уязвимость Meltdown, описанная в статье, требует как спекулятивного, так и внепланового исполнения. Тем не менее, это действительно расплывчатое утверждение, поскольку существует множество различных спекулятивных и нестандартных реализаций исполнения. Расплавление не работает только с любым типом OOO или спекулятивным исполнением. Например, ARM11 (используется в Raspberry Pis) поддерживает ограниченное количество OoO и спекулятивное выполнение, но не уязвимо.
Связанный: В чем разница между суперскалярным и OoO исполнением?,
Мне все еще трудно понять, как Meltdown использует умозрительное исполнение. В примере, приведенном в статье (тот же, что я упоминал здесь ранее), используется только IMO OoO - @Name в комментарии
Расплавление основано на процессорах Intel, которые оптимистично полагают, что нагрузки не будут давать сбой, и что если сбойная нагрузка достигнет портов нагрузки, то это было результатом ранее ошибочно предсказанной ветви. Таким образом, загрузка uop будет помечена, поэтому она выйдет из строя, если достигнет выхода на пенсию, но выполнение будет продолжаться спекулятивно с использованием данных, содержащихся в записи таблицы страниц, которые запрещают читать из пространства пользователя.
Вместо того чтобы запускать дорогостоящее восстановление исключений при выполнении нагрузки, она ждет, пока она определенно не выйдет на пенсию, потому что это дешевый способ для механизма обработать пропущенную ветвь -> случай плохой нагрузки. В аппаратном обеспечении трубе легче поддерживать трубопровод, если вам не нужно, чтобы она остановилась / остановилась для правильности. Например, загрузка, в которой вообще нет записи в таблице страниц и, следовательно, отсутствует TLB, должна ждать. Но ожидание даже при попадании в TLB (для записи с разрешениями, которые блокируют его использование) добавило бы сложности. Обычно ошибка страницы возникает только после сбоя при просмотре страницы (который не находит запись для виртуального адреса), или при прекращении загрузки или хранения, в котором не удалось получить разрешения для записи TLB, к которой она обращалась.
В современном конвейерном процессоре OoO все инструкции считаются спекулятивными до выхода на пенсию. Только после выхода на пенсию инструкции становятся не спекулятивными. Механизм Out-of-Order на самом деле не знает и не заботится, спекулирует ли он на одной стороне ветви, которая была предсказана, но еще не выполнена, или спекулирует прошлыми потенциально неисправными нагрузками. "Предположение" о том, что загрузка не вызывает сбоев, или инструкции ALU не вызывают исключений, происходит даже в процессорах, которые на самом деле не считаются спекулятивными, но полностью неупорядоченное выполнение превращает это в просто еще один вид спекуляций.
Меня не слишком беспокоит точное определение "спекулятивного исполнения", а также то, что имеет значение, а что нет. Меня больше интересует, как на самом деле работают современные нестандартные конструкции, и что на самом деле проще даже не пытаться отличить спекулятивное от не спекулятивного до конца конвейера. Этот ответ даже не пытается обратиться к более простым порядковым конвейерам с умозрительной выборкой команд (основанной на предсказании ветвления), но не с выполнением или где-то между этим и полноценным алгоритмом Томасуло с планировщиком ROB + с OoO exec + in порядок выхода на пенсию за точными исключениями.
Например, только после выхода из строя хранилище может фиксировать данные из буфера хранилища в кэш L1d, но не раньше. И чтобы поглотить короткие всплески и промахи в кэше, это не должно происходить как часть выхода на пенсию. Таким образом, одна из единственных не спекулятивных вещей не по порядку - это привязка магазинов к L1d; они определенно произошли с точки зрения архитектурного состояния, поэтому они должны быть завершены, даже если происходит прерывание / исключение.
Механизм отказа, если достигнуто, является хорошим способом избежать дорогостоящей работы в тени ошибочного прогноза филиала. Это также дает процессору правильное архитектурное состояние (значения регистров и т. Д.), Если исключение срабатывает. Вам это нужно, независимо от того, позволяете ли вы механизму OoO продолжать выполнять инструкции после того, как вы обнаружили исключение.
Пропуски ветвления являются особыми: существуют буферы, которые записывают микроархитектурное состояние (например, распределение регистров) в ветвях, поэтому восстановление ветвей может откатиться к этому, вместо того чтобы очищать конвейер и перезапускать из последнего известного исправного состояния выхода из системы. Филиалы действительно неправильно прогнозируют реальный код. Другие исключения очень редки.
Современные высокопроизводительные процессоры могут сохранять (не по порядку) выполнение мопов до того, как пропустит переход, при этом отбрасывая моп и результаты выполнения после этого момента. Быстрое восстановление намного дешевле, чем отбрасывать и перезапускать все из состояния выхода на пенсию, которое потенциально далеко отстает от точки, в которой был обнаружен неправильный прогноз.
Например, в цикле инструкции, которые обрабатывают счетчик цикла, могут значительно опередить остальную часть тела цикла и обнаружить неверный прогноз в конце достаточно быстро, чтобы перенаправить интерфейс и, возможно, не потерять значительную реальную пропускную способность, особенно если узким местом была задержка цепочки зависимостей или что-то иное, чем пропускная способность uop.
Этот оптимизированный механизм восстановления используется только для ветвей (поскольку буферы моментальных снимков состояния ограничены), поэтому пропуски ветвей относительно дешевы по сравнению с полными сбросами конвейера. (например, на Intel, машина упорядочения памяти очищает, счетчик производительности machine_clears.memory_ordering
: Каковы затраты времени ожидания и пропускной способности совместного использования производителем и потребителем места в памяти между гипер-братьями и сестрами и не-гипер-братьями и сестрами?)
Исключения не являются неслыханными, хотя; сбои страниц происходят в обычном режиме работы. например, сохранение на странице только для чтения запускает копирование при записи. Загрузка или сохранение на не отображенную страницу запускает загрузку страницы или обработку отложенного отображения. Но тысячи или миллионы инструкций обычно выполняются между каждой ошибкой страницы даже в процессе, который часто выделяет новую память. (1 на микро или миллисекунды на 1 ГГц процессоре). В коде, который не отображает новую память, вы можете идти намного дольше без исключений. В основном, просто прерывание по таймеру, время от времени при чистом переборе чисел без ввода-вывода.
Но в любом случае, вы не хотите запускать очистку конвейера или что-то дорогое, пока не будете уверены, что исключение действительно сработает. И вы уверены, что у вас есть правильное исключение. например, возможно, адрес загрузки для более ранней сбойной загрузки не был готов так скоро, поэтому первая сбойная сбойная загрузка, которая будет выполнена, была не первой в программном порядке. Ожидание выхода на пенсию - дешевый способ получить точные исключения. Дешевый с точки зрения дополнительных транзисторов, чтобы справиться с этим делом, и позволить обычному механизму выхода на пенсию выяснить, какие именно исключения происходят быстро.
Бесполезная работа, выполняемая при выполнении инструкций после команды, помеченной как ошибка при выходе на пенсию, стоит совсем немного энергии и не стоит блокировать, потому что исключения встречаются так редко.
Это объясняет, почему имеет смысл проектировать оборудование, которое было уязвимо в первую очередь для Meltdown. Очевидно, что продолжать это делать небезопасно, теперь, когда об этом думают.
Исправление Meltdown дешево
Нам не нужно блокировать спекулятивное выполнение после ошибочной загрузки; нам просто нужно убедиться, что он на самом деле не использует конфиденциальные данные. Проблема заключается не в том, что нагрузка преуспевает спекулятивно, а Meltdown основана на следующих инструкциях, использующих эти данные для создания зависимых от данных микроархитектурных эффектов. (например, касание строки кэша на основе данных).
Таким образом, если порты загрузки маскируют загруженные данные на ноль или что-то еще, а также устанавливают флаг отказа при выходе из строя, выполнение продолжается, но не может получить никакой информации о секретных данных. Это должно занять примерно 1 дополнительную задержку шлюза критического пути, что, вероятно, возможно в портах загрузки без ограничения тактовой частоты или добавления дополнительного цикла задержки. (1 тактовый цикл достаточно длинный, чтобы логика распространялась через множество вентилей И / ИЛИ на стадии конвейера, например, полный 64-битный сумматор).
Связанный: я предложил тот же механизм для исправления HW для Meltdown в Почему процессоры AMD не менее / менее уязвимы для Meltdown и Spectre?,