Введение

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

Механизмы разъяснения памяти

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

Избегание зависимости от ВОЙНЫ и ОБЯЗАНИЯ

Значения из инструкций хранилища не связаны с системой памяти (в современных микропроцессорах, кэш ЦПУ), когда они выполняются. Вместо этого, инструкции хранилища, включая адрес памяти и данные хранилища, буферируются в очереди хранилища до тех пор, пока они не достигнут точки выхода из строя. Когда магазин отходит, он записывает свою стоимость в систему памяти. Это позволяет избежать проблем зависимости WAR и WAW, показанных в вышеприведенном фрагменте кода, когда более ранняя загрузка получает неправильное значение от системы памяти, потому что более позднему хранилищу было разрешено выполнять до более ранней загрузки. Кроме того, буферные хранилища до выхода из строя позволяют процессорам спекулятивно выполнять инструкции хранилища, которые следуют за инструкцией, которая может вызвать исключение (например, загрузка неправильного адреса, деление на ноль и т. Д.). или условная инструкция, направление которой (принято или не принято) еще не известно. Если инструкция, производящая исключение, не была выполнена или направление ветви было предсказано неправильно, процессор будет получать и выполнять инструкции по "неправильному пути". Эти инструкции не должны были быть выполнены вообще; исключение должно было произойти до выполнения каких-либо спекулятивных инструкций, или филиал должен был пойти в другом направлении и вызвать получение и выполнение других инструкций. Процессор должен "отбросить" любые результаты из неправильного пути, спекулятивно выполненные инструкции, когда он обнаруживает исключение или ошибочное предсказание ветки. Сложность для хранилищ заключается в том, что любые хранилища на плохом или неправильно предсказанном пути не должны были передавать свои значения в систему памяти; если хранилища передавали свои значения, было бы невозможно "отбросить" коммит, и состояние памяти машины было бы повреждено данными из инструкции хранилища, которая не должна была быть выполнена. Таким образом, без буферизации хранилища хранилища не могут выполняться до тех пор, пока все предыдущие инструкции, которые могут вызвать исключение, не будут выполнены (и не вызвали исключение), и все предыдущие направления ветви известны. Принуждение магазинов ждать, пока не будут известны указания и исключения, значительно снижает агрессивность нарушения порядка и ограничивает ILP (параллелизм уровня инструкций) и производительность. С буферизацией хранилища хранилища могут выполнять инструкции, вызвавшие исключения или нерешенные инструкции филиала, буферизируя свои данные в очереди хранилища, но не обязуясь их значениями до выхода на пенсию. Это предотвращает хранение на неправильно предсказанных или плохих путях от передачи их значений в систему памяти, при этом все еще предлагая увеличенную ILP и производительность от полного исполнения заказов магазинов.

Пересылка от хранилища к загрузке

Буферные магазины до выхода на пенсию избегают зависимости от WAW и WAR, но вводят новую проблему. Рассмотрим следующий сценарий: магазин выполняет и буферирует свой адрес и данные в очереди в магазине. Несколько инструкций позже, загрузка выполняет, что читает с того же адреса памяти, на который только что написал магазин. Если загрузка читает свои данные из системы памяти, она будет читать старое значение, которое было бы перезаписано предыдущим хранилищем. Данные, полученные загрузкой, будут неверными. Для решения этой проблемы процессоры используют метод, называемый хранилищем, для загрузки пересылки с использованием очереди хранилища. Помимо буферизации запасов до выхода на пенсию, очередь для хранения имеет вторую цель: передача данных из завершенных, но еще не вышедших на пенсию ("в полете") запасов для последующих загрузок. Вместо простой очереди FIFO очередь хранилища на самом деле является адресованной памятью (CAM), которую можно искать с помощью адреса памяти. Когда загрузка выполняется, она ищет очередь магазинов в магазинах полетов по тому же адресу, которые логически расположены раньше в порядке программы. Если соответствующий хранилище существует, нагрузка получает значение данных из этого хранилища вместо системы памяти. Если нет соответствующего хранилища, нагрузка получает доступ к системе памяти как обычно; любые предыдущие, соответствующие хранилища должны быть уже выведены из строя и зарегистрированы. Эта техника позволяет загрузкам получать правильные данные, если их склад производителя завершен, но еще не отменен. В очереди хранилища может быть несколько хранилищ к адресу памяти нагрузки. Для обработки этого случая очередь хранилища имеет приоритет, чтобы выбрать последний магазин, который логически ранее загрузки в порядке программы. Определение того, какой склад является "последним", может быть достигнуто путем прикрепления некоторой временной метки к инструкциям, когда они извлекаются и декодируются, или, в качестве альтернативы, путем знания относительного положения (слота) нагрузки по отношению к старейшим и новым магазинам в очереди в магазине.

Выявление нарушений зависимости от RAW

Современные неисправные процессоры могут использовать ряд методов для обнаружения нарушения зависимости RAW, но все методы требуют отслеживания полетных нагрузок от выполнения до выхода на пенсию. Когда загрузка выполняется, она получает доступ к системе памяти и/или очереди хранилища для получения значения данных, а затем ее адрес и данные буферируются в очереди загрузки до выхода из строя. Структура и функция очереди загрузки схожи с очереди хранения, и на самом деле в некоторых процессорах может быть объединен с очереди хранения в единой структуре, называемой очереди загрузки или LSQ. Для выявления нарушений зависимости от RAW используются или были предложены следующие методы:

Поиск CAM в очереди загрузки

При использовании этой техники очередь загрузки, как и очередь в магазине, является CAM, которая выполняет поиск с использованием адреса доступа к памяти и отслеживает все загрузки в полете. Когда хранилище выполняется, оно ищет в очереди загрузки завершенные загрузки с того же адреса, которые логически расположены позже в порядке программы. Если такая совпадающая нагрузка существует, она должна была быть выполнена до хранения и, таким образом, прочитать некорректное, старое значение из очереди системы памяти / хранения. Любые инструкции, которые использовали значение нагрузки, также использовали плохие данные. Для восстановления, если такое нарушение обнаружено, нагрузка помечается как "нарушенная" в буфере выхода из строя. Магазин остается в очереди и буфере выхода на пенсию и выходит на пенсию нормально, передавая свою стоимость в систему памяти, когда она выходит на пенсию. Однако, когда нарушенная нагрузка достигает точки выхода из строя, процессор очищает трубопровод и запускает выполнение из инструкции нагрузки. На данный момент все предыдущие магазины передали свои ценности в систему памяти. Инструкция загрузки теперь считывает правильное значение из системы памяти, и любые зависимые инструкции будут повторно выполнены с использованием правильного значения. Этот метод требует ассоциативного поиска очереди нагрузки на каждом исполнении хранилища, что потребляет энергию схемы и может оказаться трудным временем для больших очередей нагрузки. Однако он не требует каких-либо дополнительных портов памяти (кеше) или создает конфликты ресурсов с другими загрузками или хранилищами, которые выполняются.

Раскрытие неясности при выходе на пенсию

При использовании этой техники инструкции нагрузки, которые были выполнены не в порядке, выполняются повторно (они получают доступ к системе памяти и читают значение из своего адреса во второй раз), когда они достигают точки выхода из строя. Поскольку нагрузка теперь является отступающей инструкцией, она не зависит от какой-либо инструкции, которая все еще находится в полете; все хранилища перед ней перевели свои значения в систему памяти, и поэтому любое значение, прочитано из системы памяти, гарантированно будет правильным. Значение, считанное из памяти во время повторного выполнения, сравнивается с значением, полученным при первом выполнении нагрузки. Если значения одинаковы, то исходное значение было правильным, и никакого нарушения не произошло. Если значение повторного выполнения отличается от исходного значения, то произошло нарушение RAW и трубопровод должен быть очищен, потому что инструкции, зависящие от нагрузки, использовали неправильное значение. Этот метод концептуально проще, чем поиск очереди нагрузки, и он устраняет вторую CAM и ее энергоемкий поиск (очередь нагрузки теперь может быть простой очередью FIFO). Поскольку загрузка должна получить доступ к системе памяти непосредственно перед выходом на пенсию, доступ должен быть очень быстрым, поэтому эта схема опирается на быстрый кэш. Однако, независимо от того, насколько быстрым является кэш, второй доступ к системе памяти для каждой неисправной инструкции по загрузке увеличивает задержку отмены инструкции и увеличивает общее количество доступа к кэшу, которое должно быть выполнено процессором. Дополнительный доступ к кэшу может быть удовлетворен путем повторного использования существующего порта кэша; однако это создает конфликт ресурсов порта с другими нагрузками и хранилищами в процессоре, пытающихся выполнять, и, таким образом, может вызвать снижение производительности. В качестве альтернативы, дополнительный порт кэша может быть добавлен только для разъяснения нагрузки, но это увеличивает сложность, мощность и площадь кэша. Некоторые недавние работы (Roth 2005) показали способы фильтрации многих загрузок от повторного выполнения, если известно, что не могло произойти нарушение зависимости от RAW; такая техника помогла бы устранить такие задержки и ресурсные конфликты. Незначительным преимуществом этой схемы (по сравнению с поиском очереди загрузки) является то, что она не будет отмечать нарушение зависимости RAW и запускать очистку трубопровода, если хранилище, которое вызвало бы нарушение зависимости RAW (адрес хранилища соответствует адресу загрузки в полете), имеет значение данных, которое соответствует значению данных, уже находящемуся в кэше. В схеме поиска в очереди загрузки необходимо добавить дополнительное сравнение данных в аппаратное обеспечение поиска в очереди загрузки, чтобы предотвратить такое промывание трубопровода.

Избегание нарушений зависимости от RAW

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

Прогноз зависимости от памяти

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