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

3.5.2. Взаимное влияние данных

Обращения к данным с низкими вероятностями взаимного влияния и высокими вероятностями пути могут создать наилучшие условия для спекуляции по данным. В нижеприведенном псевдокоде принято, что вероятно конфликтные сохранения *p1и*p2, являются независимыми от переменнойvar.

p1 = /* Вероятность взаимного влияния = 0.30 */

. . .

p2 = /* Вероятность взаимного влияния = 0.40 */

. . .

= var /* Загрузка, пригодная для перемещения */

Если транслятор продвинет загрузку переменной varвыше сохранений указателейp1иp2, то:

Вероятность того, что сохранения p1 или p2 повлияют на переменную var

= 1.0 – ((Вероятность того, что р1 не повлияет на var) * (Вероятность того, что р2 не повлияет на var))

= 1.0 – (0.70 * 0.60)

= 0.58

Получена вероятность влияния перемещения вверх, т.е. с вероятностью 58%, по крайней мере, либо р1, либо р2 повлияет на загрузку из var, если она будет передвинута выше их. Компилятор может использовать традиционную эвристику относительно взаимного влияния данных и информацию доступа к межпроцедурной памяти для оценки этих вероятностей.

При продвижении загрузок мимо вызовов функций должно учитываться следующее:

  • Если вызываемая функция содержит в себе много сохранений, то весьма вероятно, что будет конфликт между фактическими и альтернативными элементами ALAT.

  • Если внутри вызванной функции выполняются предварительные загрузки, то, возможно, что номера их физических регистров, либо будут идентичны, либо будут противоречить элементам ALATвыделенным в родительской функции.

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

3.5.3. Оптимизация размера кода

Часть решения состоит в том, что спекуляция должна включать рассмотрение любых возможных увеличений в размере кода. Такое рассмотрение не является особенностью спекулятивности, но относится к любым преобразованиям, которые приводят к дублированию кода, таким как, развертывание циклов, встраивание процедур или дублирование последних элементов (tail).Технологии минимизации роста кода обсуждаются в этом разделе позже.

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

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

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

Блок A

Блок B

Блок C

st

ld

Рис. 3.3. Минимизация размеров кода при спекуляции.

Если бы компилятор или программист продвинули бы загрузку из первоначальной не спекулятивной позиции до блока B, то весь спекулятивный код нужно было бы дублировать в обоих блокахBиC. Этот дублирующий код мог бы занять существующиеNOPслоты. Но если нет доступного места, то было бы желательно продвинуть загрузку до блокаA, тем более что в этом случае потребуется только одна копия.