Есть ли какое-либо преимущество использования энергозависимого ключевого слова по контрасту для использования Взаимно блокируемого класса?

Хотя не строго основанный на программировании, я наслаждался много Одиссея Робота , игра, где Вы соединили логические элементы проводом к датчикам и двигателям в роботе, чтобы заставить ее переместиться и реагировать на среду, выйти из города, выйдя из препятствий. Я играл в на Apple//e, это была одна из лучших игр на этом компьютере (с Бегуном Кладезя!:-)).

8
задан codymanix 9 November 2009 в 14:15
поделиться

5 ответов

РЕДАКТИРОВАТЬ: вопрос в значительной степени переписан

Чтобы ответить на этот вопрос, я немного углубился в вопрос и узнал кое-что о volatile и Interlocked , о котором я не знал. Давайте проясним это не только для меня, но и для этого обсуждения и других людей, читающих об этом:

  • volatile чтение / запись должны быть невосприимчивы к переупорядочению. Это только означает чтение и запись, оно не означает какое-либо другое действие;
  • волатильность не навязывается ЦП, т. Е. Аппаратному уровню (x86 использует захват и снять ограничения на любые чтение / запись). Это предотвращает оптимизацию компилятора или среды CLR;
  • Interlocked использует атомарные инструкции сборки для CompareExchange ( cmpxchg ), Приращение ( inc ) и т.д .;
  • Interlocked иногда использует блокировку: аппаратная блокировка в многопроцессорных системах ; в однопроцессорных системах аппаратная блокировка отсутствует;
  • Interlocked отличается от volatile тем, что он использует полное ограждение , где volatile использует половинное ограждение.
  • Чтение после записи может быть переупорядочено при использовании энергозависимого . Этого не может случиться с Interlocked . VolatileRead и VolatileWrite имеют ту же проблему переупорядочения, что и `volatile (ссылка благодаря Брайану Гидеону).

Теперь, когда у нас есть правила, мы можем дать ответ на ваш вопрос:

  • Технически: да,
    1. Синтаксис: нельзя записать a = b , где a или b является непостоянным, но это очевидно;
    2. Вы можете прочитать другое значение после того, как вы запишете его в изменчивую переменную из-за переупорядочения. Вы не можете сделать это с помощью Interlocked . Другими словами: вы можете быть менее безопасным с volatile , тогда вы можете быть с Interlocked .
    3. Производительность: volatile быстрее затем Interlocked .
  • Семантически: нет, потому что Interlocked просто предоставляет расширенный набор операций и его безопаснее использовать, потому что он применяет полное ограждение. Вы можете' x ++; // неатомный статический int y = 0; Interlocked.Increment (y); // атомарный

  • Область действия: да, объявление переменной volatile делает ее изменчивой для каждого отдельного доступа. Невозможно заставить это поведение каким-либо другим способом, поэтому volatile не может быть заменен на Interlocked . Это необходимо в сценариях, когда другие библиотеки, интерфейсы или оборудование могут получить доступ к вашей переменной и обновить ее в любое время, или если вам нужна самая последняя версия.

Если вы спросите меня, этот последний бит является реальной потребностью в volatile и может сделать его идеальным, когда два процесса совместно используют память и должны читать или писать без блокировки. Объявление переменной как volatile намного безопаснее в этом контексте, чем принуждение всех программистов использовать Interlocked (что вы не можете заставить компилятор).


EDIT: следующая цитата была частью моего первоначального ответа, я методы, которые считают, что переупорядочить инструкции могут привести к неожиданным и непредсказуемые результаты в многопоточные программы, которые обращаются к поля без синхронизации, такие как что предусмотрено оператором блокировки . Эти оптимизации могут быть выполнены компилятор исполняющей системой, или аппаратно. Для нестабильных полей такие оптимизации переупорядочения ограничено:

  • Чтение изменчивого поля называется изменчивым чтением . Неустойчивое чтение имеет: приобретать семантику ", то есть гарантированно произойдет до любого ссылки на память, которые появляются после это в последовательности команд.

  • Запись энергозависимого поля называется энергозависимой записью . А летучая запись имеет "выпуск" семантика ", то есть гарантировано происходить после любых обращений к памяти до инструкции записи в последовательность инструкций.

Обновление: вопрос в значительной степени переписан, исправлен мой исходный ответ и добавлен «настоящий» ответ

17
ответ дан 5 December 2019 в 10:03
поделиться

Да - вы можете посмотреть значение напрямую.

Если вы ТОЛЬКО используете Блокированный класс для доступа к переменной, тогда нет никакой разницы. Что делает volatile , так это то, что он сообщает компилятору, что переменная является особенной, и при оптимизации не следует предполагать, что значение не изменилось.

Использует этот цикл:

bool done = false;

...

while(!done)
{
... do stuff which the compiler can prove doesn't touch done...
}

Если вы установите ] done to true в другом потоке вы ожидаете выхода из цикла. Однако - если done не помечено как volatile , то у компилятора есть возможность понять, что код цикла никогда не может измениться done , и он может оптимизировать сравнение для выхода.

0
ответ дан 5 December 2019 в 10:03
поделиться

Я не буду пытаться быть авторитетом по этой теме, но я настоятельно рекомендую вам ознакомиться с этой статьей хваленым Джоном Скитом.

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

0
ответ дан 5 December 2019 в 10:03
поделиться

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

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

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

-1
ответ дан 5 December 2019 в 10:03
поделиться

Это довольно сложная тема. Я считаю, что статья Джозефа Альбахари является одним из наиболее исчерпывающих и точных источников концепций многопоточности в .NET Framework, которые могут помочь ответить на ваш вопрос.

Но, чтобы быстро резюмировать, есть много совпадений. между ключевым словом volatile и классом Interlocked , насколько они могут быть использованы. И, конечно же, и то, и другое выходит за рамки того, что вы можете сделать с обычной переменной.

1
ответ дан 5 December 2019 в 10:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: