Почему не все переменные-члены должны быть изменчивыми для обеспечения безопасности потоков даже при использовании MonitC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Почему не все переменные-члены должны быть изменчивыми для обеспечения безопасности потоков даже при использовании Monit

Сообщение Anonymous »

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

Этот вопрос проистекает из разногласий о том, что без энергозависимости компилятор (теоретически может оптимизировать любую переменную различными способами, включая сохранение ее в регистре ЦП.) Хотя в документах говорится, что это не требуется при использовании синхронизации, например блокировки переменных. Но на самом деле в некоторых случаях, по-видимому, компилятор/jit не может знать, будете ли вы использовать их или нет в своем пути к коду. Таким образом, есть подозрение, что здесь действительно происходит что-то еще, чтобы заставить модель памяти "работать".

В этом примере что мешает компилятору/jit оптимизировать _count в регистр и таким образом, приращение выполняется в регистре, а не непосредственно в памяти (позже запись в память после вызова выхода)? Если бы _count был изменчивым, казалось бы, всё было бы хорошо, но большая часть кода написана без изменчивости. Имеет смысл знать, что компилятор не должен оптимизировать _count в регистр, если он увидел в методе объект блокировки или синхронизации... но в этом случае вызов блокировки находится в другой функции.

В большей части документации говорится, что вам не нужно использовать Volatible, если вы используете вызов синхронизации, например lock.

Так что же мешает компилятору оптимизировать _count в регистр и потенциально обновить только регистр внутри блокировки? У меня такое ощущение, что большинство переменных-членов не будут оптимизированы в регистры именно по этой причине, поскольку тогда каждая переменная-член действительно должна быть изменчивой, если только компилятор не скажет, что ее не следует оптимизировать (в противном случае я подозреваю, что тонны кода потерпят неудачу). . Несколько лет назад я видел нечто подобное, глядя на C++. Локальные функциональные переменные сохранялись в регистрах, а переменные-члены класса — нет.

Итак, главный вопрос заключается в том, действительно ли это единственный способ каким образом это возможно работает без изменчивости, что компилятор/jit не будет помещать переменные-члены класса в регистры, и, следовательно, изменчивость становится ненужной?

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

public class MyClass
{
object _o=new object();

int _count=0;

public void Increment()
{
Enter();
// ... many usages of count here...
count++;
Exit();
}

//lets pretend these functions are too big to inline and even call other methods
// that actually make the monitor call (for example a base class that implemented these)
private void Enter() { Monitor.Enter(_o); }
private void Exit() { Monitor.Exit(_o); } //lets pretend this function is too big to inline
// ...
// ...
}


Подробнее здесь: https://stackoverflow.com/questions/258 ... en-using-m
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»