Подтвердить что ты не робот

Является ли запись в память наблюдаемым поведением?

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

1.9-8, по-видимому, определяет очень ограниченное наблюдаемое поведение, но указывает, что реализация может определить больше. Можно ли предположить, что любой качественный компилятор будет рассматривать изменение памяти как наблюдаемое поведение? То есть, это может не гарантировать атомарность или упорядочение, но гарантирует, что данные в конечном итоге будут записаны.

Итак, я упустил что-то в стандарте или написал в память только то, что решает компилятор?

Заявления из текущего или стандарта С++ 0x хороши. Обратите внимание: я не говорю о доступе к памяти через функцию, я имею в виду прямой доступ, например, запись данных в указатель (возможно, извлечение через mmap или другую библиотечную функцию).

4b9b3361

Ответ 1

Это то, для чего существует volatile. Иначе писать в память и никогда, по-видимому, не читать из нее не наблюдаемое поведение. Однако в общем случае оптимизатору было бы невозможно доказать, что вы никогда не читаете его, кроме как относительно тривиальных примеров, поэтому обычно это не проблема.

Ответ 2

Можно ли предположить, что любой качественный компилятор будет рассматривать изменение памяти как наблюдаемое поведение?

Нет. Летучие средства предназначены для маркировки этого. Однако вы не можете полностью доверять компилятору даже после добавления изменчивого классификатора, по крайней мере, как сказано в статье 2008 года: http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf

EDIT:

Из стандарта C (не С++) http://c0x.coding-guidelines.com/5.1.2.3.html

Фактическая реализация не должна оценивать часть выражения, если она может вывести, что ее значение не используется, и что не создаются необходимые побочные эффекты (в том числе любые вызванные вызовом функции или доступом к летучим объектам).

Ответ 3

Мое чтение C99 заключается в том, что если вы не укажете volatile, то, как и когда фактическая доступная переменная реализуется, определяется реализация. Если вы укажете квалификатор volatile, тогда код должен работать в соответствии с правилами абстрактной машины.

Соответствующими частями стандарта являются: 6.7.3 Type qualifiers (volatile description) и 5.1.2.3 Program execution (определение абстрактной машины).

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

И привязка BTW к доступу в функции не изменяет этого, поскольку функция, даже без встроенного, может быть все еще встроена компилятором в текущем блоке компиляции.

Из вашего вопроса ниже:

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

На MSalters ниже:

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