Скачиваний:
56
Добавлен:
16.04.2013
Размер:
148.99 Кб
Скачать

3.4.2.1. Примеры предварительных загрузок

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

st8 [r4]=r12 // Такт 0: неоднозначное сохранение

ld8 r6=[r8];; // Такт 0: загрузка, нужная далее

add r5=r6,r7;; // Такт 2

st8 [r18]=r5 // Такт 3

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

ld8.a r6=[r8] // Такт -2 или ранее

// Другие инструкции

st8 [r4]=r12 // Такт 0: неоднозначное сохранение

ld8.c r6=[r8] // Такт 0: проверка загрузки

add r5=r6,r7;; // Такт 0

st8 [r18]=r5 // Такт 1

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

3.4.2.2. Пример кода восстановления

Рассмотрим снова не спекулятивный код из последнего раздела:

st8 [r4]=r12 // Такт 0: неоднозначное сохранение

ld8 r6=[r8];; // Такт 0: загрузка, нужная далее

add r5=r6,r7;; // Такт 2

st8 [r18]=r5 // Такт 3

Компилятор может передвинуть вверх не только загрузку, но также одного или нескольких ее пользователей. В этом преобразовании, для проверки правильности предварительной загрузки, лучше использовать chk.a, чем инструкциюld.c. Используем тот же самый пример кодовой последовательности, но теперь, аналогичноld8передвигаемadd. Результат таков:

ld8.a r6=[r8];; // Такт -3

// Другие инструкции

add r5=r6,r7 // Такт -1: сложение, которое использует r6

// Другие инструкции

st8 [r4]=r12 // Такт 0

chk.a r6,recover // Такт 0: проверка

back: // Точка возврата из кода восстановления

st8 [r18]=r5 // Такт 0

Также должен быть сгенерирован код восстановления:

recover:

ld8 r6=[r8] ;; // Заново загружаем r6 из [r8]

add r5=r6,r7 // Заново выполняем сложение

br back // Возврат к главному коду

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

3.4.2.3. Краткий обзор терминологии

Загрузка спекулятивная по данным (data speculative load).

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

Предварительная загрузка (advanced load).

Загрузка спекулятивная по данным.

Проверка загрузки (check load).

Инструкция, которая проверяет, нуждается ли соответствующая предварительная загрузка в исполнении заново, и если да, то запускает его.

Проверка предварительной загрузки (advanced load check).

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

Код восстановления (recovery cod).

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