Модель памяти.NET, энергозависимые переменные и тест-и-набор: что гарантируется?

Я знаю что модель памяти.NET (на Платформе.NET; не compact/micro/silverlight/mono/xna/what-have-you), гарантировал, что для определенных типов (прежде всего примитивные целые числа и ссылки) операции, как гарантировали, будут атомарными.

Далее, я полагаю что x86/x64 инструкция теста-и-набора (и Interlocked.CompareExchange) на самом деле ссылается на местоположение глобальной памяти, поэтому если оно следует за другим Interlocked.CompareExchange видел бы новое значение.

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

Это приводит к нескольким вопросам:

  1. Мои верования выше корректного?
  2. Interlocked.Read не имеет перегрузки для интервала, только для longs (которые являются 2 СЛОВАМИ и таким образом обычно не читаются атомарно). Я всегда предполагал, что модель памяти.NET гарантировала, что новейшее значение будет замечено при чтении ints/references, однако с кэшами процессора, регистрами, и т.д. Я начинаю видеть, что это не может быть возможно. Так есть ли способ вынудить переменную быть повторно выбранной?
  3. Энергозависим достаточный для решения вышеупомянутой проблемы для целых чисел и ссылок?
  4. На x86/x64 может я принимать это...

Если существует два глобальных X и Y целочисленных переменных, оба инициализированные к 0 это, если я пишу:

x = 1;
y = 2;

То, что НИКАКОЙ поток не будет видеть x = 0 и y = 2 (т.е. записи произойдут в порядке). Это изменяется, если они энергозависимы?

10
задан Johannes Rudolph 20 January 2010 в 20:01
поделиться

3 ответа

Я тоже достаточно новичок в Clojure и наслаждаться этим на математических проблемах, где скорость не является проблемой. Это просто так выразительно. Также очень приятно быть в состоянии использовать расширенную точность BigDecimals и Bigintegers прозрачно - не тестируют с неуклюжими конструкторами и методами, которые требует Java.

Предостережение о скорости действительно из-за моего собственного неопытности. Я не знаю, что это проблема для действительно квалифицированного. Это также область, которая поддается распараллелизу, которая, кажется, так просто в Clojure.

-121--2459753-
  • Читает только и пишет на переменные, которые находятся на большинстве 32 бита шириной (и 64 бита широко в системах X64) являются атомными. Все это означает, что вы не будете читать INT и получите полуписное значение. Это не означает арифметика атомно.
  • Заблокированные операции также действуют как барьеры памяти, поэтому да, Interlocked.compareexchange увидит обновленное значение.
  • См. Эта страница . Волатиль не означает приказ. Некоторые компиляторы могут выбрать не перезагружать операции на летучие переменные, но ЦП бесплатный для повторного заказа. Если вы хотите остановить процессор от инструкций по перегрузке, используйте (полный) барьер памяти.
  • Модель памяти гарантирует, что чтение и пишеты являются атомными, и использование волатильного ключевого слова гарантирует, что чтение будет всегда приходит из памяти, а не из реестра. Так что вы будут увидеть новейшее значение. Это связано с тем, что процессоры x86 недействительны кэш при необходимости - см. это и это . Также см. InterlockedCompareexChange64 Для того, как атомно читать 64-битные значения.
  • И, наконец, последний вопрос. Ответ - это нить, фактически видишь x = 0 и y = 2 , а использование летучего ключевого слова не изменяется, потому что CPU бесплатный для повторных заказов. Вам нужен барьер памяти.

Сводка:

  1. Компилятор бесплатный для повторных заказов инструкции.
  2. ЦП свободен заказать инструкции.
  3. Читатели и пишеты с словом являются атомные. Арифметические и другие операции не являются атомными, потому что они включают в себя чтение, вычислить, затем писать.
  4. Читатели числа слов из памяти всегда будут получать новейшее значение. Но большую часть времени вы не знаете, на самом деле вы читаете из памяти.
  5. полный барьер памяти останавливается (1) и (2). Большинство компиляторов позволяют вам остановиться (1) сам по себе.
  6. Волатильное ключевое слово гарантирует, что вы читаете с памяти - (4).
  7. Заблокированные операции (префикс блокировки) позволяют несколько операций быть атомными. Например, чтение + запись (InterlockedExchange). Или прочитанный + сравнить + запись (interlockedcompareexchange). Они также действуют как барьеры памяти, поэтому (1) и (2) останавливаются. Они всегда пишут в память (очевидно), поэтому (4) обеспечивается.
6
ответ дан 4 December 2019 в 02:26
поделиться

Можно установить таймер при нажатии или отпускании клавиши и игнорировать события KeyPress и KeyRelease, происходящие в пределах интервала повторения.

-121--1663356-

Я думаю, что вам нужно создать маркер с именем пользователя и зашифрованной последовательностью аутентификации, которую вы получите из windows Identity. Не нужно хранить пароль в файле cookie. У нас есть приложение, в котором хранятся имя пользователя и аутентифицированная последовательность

-121--978559-

Нет, изменчивое ключевое слово и гарантия атомарности слишком слабы. Для этого нужен барьер памяти. Его можно получить явным образом с помощью метода Thread.MemureBarrier ().

0
ответ дан 4 December 2019 в 02:26
поделиться

Обнаружил этот старый поток. Все ответы Ханса и wj32 верны, за исключением части, касающейся volatile .

Конкретно по поводу вашего вопроса

Могу ли я предположить, что на x86 / x64 ... Если есть две глобальные целочисленные переменные x и y, оба инициализируются значением 0, если Я пишу: х = 1; y = 2;

Этот НЕТ поток не увидит x = 0 и y = 2 (т.е. запись будет происходят по порядку).Изменится ли это, если они изменчивы?

Если y является изменчивым, запись в x гарантированно произойдет до записи в y , поэтому ни один поток никогда не увидит x = 0 и y = 2 . Это связано с тем, что запись в изменчивую переменную имеет «семантику выпуска» (логически эквивалентную выбросу ограничения выпуска), то есть все инструкции чтения / записи до того, как она перестанет перемещаться, передают ее. (Это означает, что если x является изменчивым, а y - нет, вы все равно можете увидеть неожиданные x = 0 и y = 2 .) См. Описание и пример кода в ] Спецификация C # для получения более подробной информации.

2
ответ дан 4 December 2019 в 02:26
поделиться
Другие вопросы по тегам:

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