Что делает небезопасным хранение значения в регистре?

Говоря о распределении регистров, в текстах по компиляции (например, «Разработка компилятора» Купера) часто упоминается, что значения, хранящиеся в регистрах, должны быть «безопасными», иначе их следует хранить в памяти.

Что делает небезопасным хранение значения в регистре?

Изменить: Контекст из книги:

«В модели «память-в-память» распределитель должен определить, какие значения можно безопасно хранить в регистрах, то есть какие значения являются однозначными».

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

Итак, чтобы прояснить вопрос: почему значение указателя небезопасно хранить в регистре, и является ли это единственным случаем, когда значение не может быть безопасно сохранено в регистре?


person mijiturka    schedule 05.02.2015    source источник
comment
Было бы полезно привести цитату Купера, используя сейф в контексте и/или поиск сейфа в указателе книги.   -  person Jeffrey Bosboom    schedule 05.02.2015
comment
Спасибо, я отредактировал вопрос сейчас.   -  person mijiturka    schedule 05.02.2015
comment
Я не уверен в первой цитате, но вторая касается анализа псевдонимов - когда компилятор может доказать, что значение, загруженное через указатель, не изменится на протяжении всего цикла, поэтому его не нужно загружать на каждой итерации.   -  person Jeffrey Bosboom    schedule 05.02.2015


Ответы (3)


Насколько я понимаю, это в основном вопрос aliases. Псевдонимы — это два или более имен, которые относятся к одному и тому же объекту в какой-то точке программы.

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

int first, second, *p, *q;
...
first = *p; // store the value from the variable referred to by p in first
*q = 3;     // assign to the variable referred to by q
second = *p;     // store the value from the variable referred to by p in second

Первоначальное присвоение first на большинстве машин требует загрузки *p в регистр. Поскольку доступ к памяти обходится дорого, компилятор захочет сохранить загруженное значение и повторно использовать его в присваивании second. Однако он не сможет этого сделать, если не сможет убедиться, что p и q не относятся к одному и тому же объекту (что *p и *q не являются псевдонимами).

Анализ, выполняемый для проверки того, что определенные имена не являются псевдонимами, называется alias analysis и определяет, когда значения могут быть безопасно кэшированы в регистрах, вычислены «не по порядку» или доступны для параллельных потоков.

person NlightNFotis    schedule 06.02.2015

Немного другой код:

static int x;
int* p;
int first, second;

first = x;
*p = 3;
second = x;

Присваивание *p могло изменить x, поэтому присваивание second = x должно снова прочитать x из памяти и не может использовать значение, которое только что было сохранено в first и которое, вероятно, все еще находится в регистре.

person gnasher729    schedule 06.02.2015

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

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

Лучше всего проверить соответствующие руководства, если вы используете переменные-указатели, которые собираетесь помещать в регистры.

person Shivaraj Bhat    schedule 06.02.2015