
- •2. Введение в программирование для архитектуры IntelItanium
- •2.1. Обзор
- •2.2. Регистры
- •2.3. Использование инструкций IntelItanium
- •2.3.1. Формат
- •2.3.2. Выраженный параллелизм
- •2.3.3. Связки и шаблоны
- •2.4. Доступ к памяти и спекуляция
- •2.4.1. Функциональные возможности.
- •2.4.2. Спекулятивность
- •2.4.3. Спекуляция по управлению
- •2.4.4. Спекуляция по данным
- •2.5. Предикация
- •2.6. Архитектурная поддержка и вызовы процедур
- •2.6.1. Стековые регистры
- •2.6.2. Механизм регистрового стека
- •2.7. Переходы и Подсказки
- •2.7.1. Инструкции перехода
- •2.7.2. Циклы и программная конвейерная обработка
- •2.7.3. Ротация регистров
- •2.8. Итоги
2.4. Доступ к памяти и спекуляция
Архитектура Itaniumобеспечивает доступ к памяти только через инструкции загрузки и сохранения регистра и через специальные семафорные инструкции. Также, архитектура обеспечивает обширную поддержку для сокрытия времени ожидания памяти через спекуляцию контролируемую программистом.
2.4.1. Функциональные возможности.
К данным и инструкциям обращаются с помощью 64-битных адресов. Инструкции хранятся в памяти с упорядочиванием байт по убыванию, т.е. наименее значимый байт появляется в младшем адресе места памяти. Для данных поддерживаются оба режима упорядочивания байт – и по возрастанию и по убыванию – этим управляет бит в регистре маски пользователя.
При целочисленных загрузках одного, двух или четырех байтов, их значения расширяются нулем, поскольку в любом регистре, всегда записываются все 64-бита. Целочисленные сохранения записывают один, два, четыре или восемь байтов из регистра в память именно так, как это задается.
2.4.2. Спекулятивность
Спекулятивность позволяет программисту нарушать зависимости по данным или управлению, которые обычно ограничивают движение кода. Два типа спекулятивности называются: спекуляцией по управлению и спекуляцией по данным. Этот раздел суммирует спекулятивность в архитектуре Itanium. Для более детального описания спекулятивного поведения инструкции и приложения см. ниже главу 3 «Обращения к памяти».
2.4.3. Спекуляция по управлению
Спекуляция по управлению позволяет использовать загрузки и их зависимость для безопасного перемещения выше переходов. Поддержка этого обеспечивается специальными битами NaT, которые присоединены к целочисленным регистрам и специальными значениямиNatValдля регистров с плавающей точкой. Если спекулятивная загрузка приводит к исключению, то оно не вызывается немедленно. Вместо этого, в принимающем регистре устанавливается битNaT(либо в регистр с плавающей точкой записывается значениеNatVal). Последующие спекулятивные инструкции, которые используют регистр с установленным битомNaT, распространяет установку до тех пор, пока не спекулятивная инструкция не проверит или не вызовет задержанное исключение.
Например, в приведенной ниже последовательности, при отсутствии другой информации, компилятор в типичной RISCархитектуре, не может безопасно перемещать загрузку выше перехода:
(p1) br.cond.dptk L1// Такт 0
ld8 r3=[r5];; // Такт 1
shr r7=r3,r87 // Такт 3
Предположим, что время ожидания загрузки – 2 такта, инструкция сдвига вправо (shr) остановится после 1. Однако, используя спекулятивные загрузки и проверки, обеспечиваемые в архитектуреItanium, два такта могут быть сэкономлены, если переписать вышеупомянутый код так, как это показано ниже:
ld8.s r3=[r5] // Предварительный такт
// Другие инструкции
(p1) br.cond.dptk L1;; // Такт 0
chk.s r3,recovery // Такт 1
shr r7=r3,r87 // Такт 1
Этот код предполагает, что r5 готов к моменту обращения и что имеется достаточно инструкций, чтобы заполнить время ожидания между ld8.s и chk.s.
2.4.4. Спекуляция по данным
Спекуляция по данным позволяет перемещать загрузки выше возможных конфликтных обращений к памяти. Расширенные загрузки обращаются исключительно к спекулятивным загрузкам по данным. Рассмотрим порядок загрузок и сохранений в данной ассемблерной последовательности:
st8 [r55]=r45 // Такт 0
ld8 r3=[r5] ;;// Такт 0
shr r7=r3,r87 // Такт 2
Архитектура Itaniumпозволяет программисту перемещать загрузку выше сохранения, даже если не известно, ссылаются ли загрузка и сохранение на перекрывающиеся места памяти. Это делается путем использования специальных инструкций предварительной загрузки и проверки:
ld8.a r3=[r5] // Предварительная загрузка
// Другие инструкции
st8 [r55]=r45 // Такт 0
ld8.c r3=[r5] // Такт 0 - проверка
shr r7=r3,r87 // Такт 0
Примечание. В этом варианте, инструкцияshrможет запускаться в такте 0, если не было никаких конфликтов между предварительной загрузкой и прошедшими сохранениями. Если конфликт был, то инструкция проверки загрузки (ld8.c) обнаружила бы конфликт и перезапустила бы загрузку.