Здравствуйте, drol, Вы писали:
КД>>Я правильно понимаю, что вызов MemoryBarrier предотвращает возможность трансформации get_data (в процессе компиляции с оптимизацией) в код вида
D>Нет, Вы всё понимаете абсолютно неправильно.
D>MemoryBarrier не имеет (почти) никакого отношения к оптимизациям компилятора. Более того, в данном примере совершенно очевидно, что "код вида" однопоточно неэквивалентен исходному коду — бо там два обращения к m_Options против одного в оригинале. И поэтому никакая оптимизация — хоть компилятора, хоть процессора — такую трансформацию сделать не может.
Ага. Ну вообщем, я так тоже думал... Но потом подумал — а вдруг ...
Смотрю в FW примеры с использованием Thread.MemoryBarrier() и мой моск воспринимает это именно как борьбу с "оптимизацией" в виде удаления локальных переменных
Например.
//System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
ConcurrentDictionary<TKey, TValue>.Node[] buckets = this.m_buckets;
for (int i = 0; i < buckets.Length; i++)
{
ConcurrentDictionary<TKey, TValue>.Node node = buckets[i];
Thread.MemoryBarrier();
while (node != null)
{
yield return new KeyValuePair<TKey, TValue>(node.m_key, node.m_value);
node = node.m_next;
}
}
yield break;
}
Мне, вообщем-то, нужна гарантия что значение из m_Options сначала будет прочитана в локальную переменную, а потом мы будем работать именно с этой локальной переменной.
Содержимое m_Options константно.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --