Метод доступа для волатильных членов - PullRequest
1 голос
/ 21 февраля 2012

У нас есть оболочка, представляющая атомное целое число. Внутренне он реализован с использованием функций InterlockedIncrement() и InterlockedDecrement() Windows, которые работают с переменной volatile long:

class AtomicInt {
public:
    ...

    operator long() const { return m_value; }

private:
    volatile long m_value;
};

Мой вопрос: является ли приведенный выше оператор для запроса текущего значения правильным (т. Е. Вы всегда получаете текущее значение) или мне нужно объявить метод также как volatile, чтобы предотвратить любые проблемы с кэшированными значениями?

Ответы [ 2 ]

2 голосов
/ 21 февраля 2012

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

Кстати, для дальнейшего использования, имейте в виду, что в многопроцессорной среде вне x86 ключевое слово volatile недостаточно, чтобы гарантировать, что поток, использующий значение вашей совместно используемой памяти, не получит кэшированные данные. Ключевое слово volatile в целом просто предотвращает некоторые оптимизации компилятора. Однако на процессорных платформах с более слабыми правилами согласованности памяти (например, ARM, PowerPC и т. Д.) Вы все равно можете получить доступ к кэшированному значению из локального ядра процессора, даже если переменная помечена как энергозависимая. Обходной путь заключается в том, чтобы реализовать надлежащие барьеры памяти, чтобы гарантировать, что любые устаревшие значения в реальных кэшах памяти процессора сбрасываются и обновляются. Это, конечно, платформо-зависимые инструкции ... хорошая новость в вашем случае - это то, что используемые вами компиляторы гарантируют, что вы не столкнетесь с этими проблемами в своем классе AtomicInt, но я хотел, чтобы вы знали этой общей проблемы, связанной с ключевым словом volatile.

0 голосов
/ 21 февраля 2012

Достаточно сделать m_value летучим. Этого достаточно, чтобы остановить оптимизацию метода доступа.

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