С# - "Неустойчиво" действительно необходимо как ключевое слово?

Поскольку я читаю все глубже и глубже в значении ключевого слова volatile, я все время говорю себе: "Это путь к реализации , это не должно быть частью языка программирования высокого уровня".
Я имею в виду, что тот факт, что ЦП кэшировать данные, должен быть интересен компилятору JIT, а не программисту на С#.

Значительная альтернатива может быть атрибутом (например, VolatileAttribute).

Как вы думаете?

Ответы

Ответ 1

Я думаю, вы получили побочные следы. Все технические материалы о кешировании и т.д. Являются частью попытки объяснить это на условиях низкого уровня. Функциональное описание для volatile было бы "Я мог бы быть общим". Учитывая, что по умолчанию ничто не может делиться между потоками, это не совсем странно. И я думаю, достаточно фундаментальный, чтобы гарантировать ключевое слово по атрибуту, но я полагаю, что на него в значительной степени влияли исторические решения (С++)

Один из способов их замены/оптимизации - вызовы VolatileRead() и VolatileWrite(). Но это еще более "реализация".

Ответ 2

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

У аппаратных парней много работы. Ключевое слово volatile имеет много процессорных ядер со слабой моделью памяти. Рынок не был добр к ним, Alpha и Itanium не преуспели. Не совсем понятно, почему, но я подозреваю, что сложность написания твердого кода с резьбой для этих ядер имеет много общего с этим. Неправильно, это довольно кошмар для отладки. Сложность в документации библиотеки MSDN для volatile относится к этим типам процессоров, в противном случае она совершенно неуместна для ядер x86/x64 и заставляет задуматься, что ключевое слово делает гораздо больше, чем на самом деле. Volatile просто предотвращает сохранение значений переменных в регистрах CPU на этих ядрах.

К сожалению, неустойчивость по-прежнему имеет значение для ядер x86 в очень определенных условиях. Я еще не нашел никаких доказательств того, что это важно для x64 ядер. Насколько я могу судить, и подкрепленный исходным кодом в SSCLI20, команда Opcodes.Volatile является no-op для джиттера x64, не меняя ни состояние компилятора, ни испуская какой-либо машинный код. Это правильное направление.

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

Ответ 3

Использование атрибута было бы приемлемым, если бы это было наоборот, то есть, компилятор предположил бы, что все переменные нестабильны, если явно не отмечены атрибутом, говорящим, что это безопасно. Это будет невероятно усложнять производительность.

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

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

Кроме того, вы, похоже, путаетесь с "деталями реализации". Этот термин относится к тому, что делает компилятор за вашей спиной. Здесь не так. Ваш код изменяет varaible вне представления компилятора. SInce это в вашем коде, это всегда будет правдой. Следовательно, langauge должен иметь возможность указать, что.

Ответ 4

IIIRC, в С++ волатильность была в основном связана с памятью ввода-вывода, а не с кешем. Если вы дважды читаете один и тот же порт, вы получаете разные ответы. Тем не менее, я согласен с вашей оценкой, что это более чисто выражено в С# в качестве атрибута.

С другой стороны, большинство фактических применений volatile в С# лучше понимать как блокировку потоков в любом случае, поэтому выбор летучих может быть немного неудачным.

Изменить: просто добавьте: две ссылки, чтобы показать, что в C/С++ `volatile является явно не для многопоточности.

Ответ 5

volatile в С# испускает правильные барьеры или заборы, что важно для программиста, выполняющего многопоточную работу. Имейте в виду, что компилятор, среда выполнения и процессор могут в некоторой степени изменить порядок чтения/записи (каждый из них имеет свои собственные правила). Хотя CLR 2.0 имеет более сильную модель памяти, которую специфицирует CLI ECMA, модель памяти CLR по-прежнему не самая строгая модель памяти, поэтому вам нужно volatile в С#.

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