- •3. Обращение к памяти
- •3.1. Краткий обзор
- •3.2. Не спекулятивные обращения к памяти
- •3.2.1. Сохранения в память
- •3.2.2. Загрузки из памяти
- •3.2.3. Подсказки предвыборки данных
- •3.3. Зависимости инструкций
- •Раздел 3.4. Описывает определенные в архитектуре Itanium, особенности обращений к памяти, увеличивающие число зависимостей, которые могут быть удалены транслятором.
- •3.3.1. Зависимости по управлению
- •3.3.1.1. Планирование инструкций и зависимости по управлению
- •3.3.2. Зависимости по данным
- •3.3.2.1. Основы зависимости по данным
- •3.3.2.2. Зависимость по данным в архитектуре IntelItanium
- •3.3.2.3. Планирование инструкций и зависимости по данным
- •3.4. Использование спекулятивности в архитектуре IntelItaniumдля преодоления зависимостей
- •3.4.1. Модель спекулятивности в архитектуре IntelItanium
- •3.4.2. Использование спекуляции по данным в архитектуре IntelItanium
- •3.4.2.1. Примеры предварительных загрузок
- •3.4.2.2. Пример кода восстановления
- •3.4.2.3. Краткий обзор терминологии
- •3.4.3. Использование спекуляции по управлению в архитектуре IntelItanium
- •3.4.3.1. Бит NaT
- •3.4.3.2. Пример спекуляции по управлению
- •3.4.3.3. Сливания, заливания и регистр unat
- •3.4.3.4. Краткий обзор терминологии
- •3.4.4. Комбинирование спекуляций по данным и управлению
- •3.5. Оптимизация обращений к памяти
- •3.5.1. Соображения о спекуляции
- •3.5.2. Взаимное влияние данных
- •3.5.3. Оптимизация размера кода
- •3.5.4. Использование постинкрементных загрузок и сохранений.
- •3.5.5. Оптимизация циклов.
- •3.5.6. Минимизация кода проверки
- •3.6. Итоги
3.5.6. Минимизация кода проверки
Проверки спекулятивных загрузок могут иногда объединяться для уменьшения размеров кода. Распространение спекулятивными инструкциями NaTбитов и значенийNaTVal, может разрешить одной проверке спекулятивного результата заменить многократные промежуточные проверки. Нижеприведенный код демонстрирует этот потенциал оптимизации:
ld4.s r1=[r10] // Спекулятивная загрузка в r1
ld4.s r2=[r20] // Спекулятивная загрузка в r2
add r3=r1,r2;; // Сложение двух спекулятивных значений
// Другие инструкции
chk.s r3,imm21 // Проверка NaT бита в r3
st4[r30]=r1 // Сохранение r1
st4[r40]=r2 // Сохранение r2
st4[r50]=r3 // Сохранение r3
Перед сохранением любого из регистров r1, r2илиr3, должен быть проверен только регистр результатаr3. Если бы во время спекулятивной загрузки по управлениюr1или r2был установленNaTбит, тоNaTбит распространился бы через инструкцию сложения от регистровr1или r2к региструr3.
Другой способ уменьшить количество кода проверки состоит в том, чтобы использовать анализ потока управления, чтобы избежать использования дополнительных инструкций ld.cилиld.a. Например, компилятор может запланировать одну проверку в том месте, которое будет достигнуто всеми копиями предварительной загрузки. Часть потокового графа, показанного на рис. 3.4 демонстрирует, как эта технология могла бы применяться.
|
Рис. 3.4. Использование одной проверки для трех предварительных загрузок
Единственная проверка для всех предварительных загрузок, показанная в самом нижнем блоке, является корректной, если выполняются оба условия:
Самый нижний блок является общим последователем всех блоков с предварительными загрузками.
Самый нижний блок предшествует любому использованию результатов предварительных загрузок.