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

StackOverflow https://stackoverflow.com/questions/1701216

Вопрос

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

Это было полезно?

Решение

Изменить: Вопрос в значительной степени переписан

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

  • volatile Читать/записать должно быть невосприимчиво к повторному заказу. Этот Только означает чтение и письмо, это делает нет означают любое другое действие;
  • волатильность не навязывается на процессоре, то есть на уровне аппаратного обеспечения (x86 использует приобретение и выпуск заборов на Любые читай пиши). Это предотвращает оптимизацию компилятора или CLR;
  • Interlocked Использует инструкции по атомной сборке для сравнения (cmpxchg), Приращение (inc) так далее;
  • Interlocked использует Иногда замок: аппаратная блокировка на многопроцессорных системах; В Uni-Processor Systems нет аппаратного блокировки;
  • Interlocked отличается от volatile в том, что он использует полный забор, где летучие использует половину забора.
  • Чтение после записи может быть переупорядочено Когда вы используете volatile. Анкет Это не может случиться с Interlocked. VolatileRead а также VolatileWrite Имейте ту же проблему переупорядочения, что и «летучая (ссылка благодаря Брайану Гидеону).

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

  • Технически: да, есть вещи, с которыми вы можете сделать volatile что вы не можете сделать с Interlocked:
    1. Синтаксис: вы не можете написать a = b куда a или же b нестабильный, но это очевидно;
    2. Вы можете прочитать другое значение после того, как напишите его в летучих переменных из -за повторного порядка. Вы не можете сделать это с Interlocked. Анкет Другими словами: вы можете быть меньше безопасно с volatile тогда вы можете быть с Interlocked.
    3. Производительность: volatile тогда быстрее Interlocked.
  • Семантически: нет, потому что Interlocked Проще говоря, обеспечивает надзор за операциями и безопаснее использовать, потому что он применяет полное ограждение. Ты ничего не можешь сделать с volatile что вы не можете сделать с Interlocked И ты можешь сделать много с Interlocked что вы не можете сделать с изменчивым:

    static volatile int x = 0;
    x++;                        // non-atomic
    static int y = 0;
    Interlocked.Increment(y);   // atomic
    
  • Область: да, объявление переменной volatile делает его нестабильным для каждого отдельного доступа. Невозможно заставить это поведение каким -либо образом, следовательно, volatile нельзя заменить на Interlocked. Анкет Это необходимо в сценариях, где другие библиотеки, интерфейсы или аппаратное обеспечение могут получить доступ к вашей переменной и обновить ее в любое время или нуждаться в самой последней версии.

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


РЕДАКТИРОВАТЬ: Следующая цитата была частью моего первоначального ответа, я оставлю его ;-)

Цитата из C# язык программирования Стандарт:

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

  • Чтение летучего поле называется нестабильное чтение. Анкет У нестабильного чтения есть: приобретение семантики »; то есть, гарантированно произойдет до любых ссылок на память, которая возникает после ее в последовательности инструкций.

  • Написать летучивое поле называется нестабильная запись. Анкет У нестабильной записи есть «семантика выпуска»; То есть это гарантированно произойдет после любых ссылок на память перед инструкцией записи в последовательности инструкций.

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

Другие советы

This is a fairly complex topic. I find Joseph Albahari's writeup to be one of the more definitive and accurate sources for multithreading concepts in the .NET Framework that might help answer your question.

But, to quickly summarizes there is a lot of overlap between the volatile keyword and the Interlocked class as far as how they can be used. And of course both go way above and beyond what you can do with a normal variable.

Yes - you can look at the value directly.

As long as you ONLY use the Interlocked class to access the variable then there is no difference. What volatile does is it tells the compiler that the variable is special and when optimizing it shouldn't assume that the value hasn't changed.

Takes this loop:

bool done = false;

...

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

If you set done to true in another thread you would expect the loop to exit. However - if done is not marked as volatile then the compiler has the option to realize that the loop code can never change done and it can optimize out the compare for exit.

This is one of the difficult things about multithread programming - many of the situations which are problems only come up in certain situations.

I won't attempt to be an authority on this subject but I would highly recommend that you take a look at this article by the vaunted Jon Skeet.

Also take a look at the final part of this answer which details what volatile should be used for.

Yes, you can gain some performance by using a volatile variable instead of a lock.

Lock is a full memory barrier which can give you the same characteristics of a volatile variable as well as many others. As has already been said volatile just ensures that in multi-threaded scenarios if a CPU changes a value in its cache line, the other CPUs sees the value immediately but do not ensure any locking semantic at all.

The thing is lock is a lot more powerful than volatile and you should use volatile when you can to avoid unnecessary locks.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top