Глобальные переменные и переменные на основе кучи всегда изменчивы в Delphi? - PullRequest
2 голосов
/ 13 декабря 2011

Я видел похожие вопросы (например, здесь и здесь ), но никогда не видел однозначного ответа.Предположим, у нас есть следующий код:

..
I:= 1;
I:= 2;
..

Является ли компилятор Delphi гарантирует, что первое назначение никогда не будет устранено оптимизатором, и реализовано путем записи данных в адрес памяти переменной I, а не только в некоторыерегистр процессора, если I является глобальной или основанной на куче (например, поле объекта) переменной?

1 Ответ

3 голосов
/ 13 декабря 2011

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

То, что это так, можно увидеть на следующем минимальном примере:

program OptimiseMe;
{$APPTYPE CONSOLE}
{$O+}//switch optimisations on
var
  I: Integer;
begin
  I := 1;
  I := 2;
  if I>0 then
    ;
end.

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

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

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

Примечание : когда вы говорите о волатильности, вы должны быть осторожны, поскольку существует множество различных определений. Значение, определенное в стандартах C и C ++, одно. Компилятор MSVC имеет соответствие стандартам, но более строгое определение. И опять по-другому в Java и C #. Здесь много сложностей, и функции InterlockedXXX - отличный способ скрыть эту сложность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...