Re[2]: Каков механизм write barrier
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 06.05.04 17:19
Оценка: 26 (2)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Serginio1, Вы писали:


VD>Я вот тоже слышал этот термин несклько раз, но он как-то упоминается в сколь. Типа "обсуждение этой фичи выходит за рамки...".

Во блин нашел аж за 1993 год
http://research.sun.com/research/self/papers/write-barrier.html
Каким то образом наверное write barier связан с GC но это возможно если учет ссылок GC был произведен, но обычно это происходит при выделении определенного количества памяти. С другой стороны на Array.Copy write-barrier практически не влияет (вернее есть небольшое замедление по сравнению с валуе типами, но не такое катострофическое, причем в видби это практически не заметно).
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[11]: Каков механизм write barrier
От: alexkro  
Дата: 01.06.04 10:17
Оценка: 22 (2)
Здравствуйте, Блудов Павел, Вы писали:

БП>Здравствуйте, Дарней, Вы писали:


Д>>всё-таки не понял. А зачем тогда MemoryBarrier вызывать?


БП>Затем, что (читайте выше) Singleton.value может быть уже не null

БП>и другой процессор уже может попытаться его исползовать. В этом
БП>случае

БП>lock(syncRoot)


БП>НЕ ПРОИСХОДИТ. Так вот, для того, чтобы Singleton.value был отправлен

БП>в память __последним__ а не каким-то, нужно и сбросить кеш.
БП>Раньше это называли FlushProcessorCache. А теперь Memory barrier.

Там даже еще похитрее будет. Memory barrier перед записью value не мешает другому потоку не увидеть данные, на которые указывает этот value. Как замечено в одном из комментариев http://blogs.msdn.com/brada/archive/2004/05/12/130935.aspx, там нужен ещё один memory barrier сразу после первого чтения Singleton.value. Тонкий момент. Многие не могут просечь (в том числе и я до конца, вероятно, не просекаю). В данном случае нужно полагаться на экспертов, которые этот вопрос разобрали и выяснили, как нужно делать правильно. Scott Meyers с этими экспертами помыкался с полгода и выдал резюме: http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf
Re: Каков механизм write barrier
От: mihailik Украина  
Дата: 13.05.04 16:36
Оценка: 19 (2)
Ещё немного из свежего блога:

volatile and MemoryBarrier() Brad Adams Blog
... << RSDN@Home 1.1.3 stable >>
Каков механизм write barrier
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 06.05.04 15:29
Оценка: +2
По данной ссылке
http://www.rsdn.ru/Forum/Message.aspx?mid=558877&amp;only=1
Автор: Yury_Malich
Дата: 03.03.04

есть обяснение почему при обмене ссылками на объекты происходит торможение раз в 10-12 по сравнению с обменами валуе типов.
В тестах http://www.rsdn.ru/Forum/Message.aspx?mid=558877#558877
Автор: Yury_Malich
Дата: 03.03.04

это очень хорошо видно

Интересен сам по себе механизм такого поведения
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[4]: Каков механизм write barrier
От: alexkro  
Дата: 15.05.04 09:15
Оценка: 27 (1)
Здравствуйте, mihailik, Вы писали:

M>>>volatile and MemoryBarrier() Brad Adams Blog

S>> Спасибо. Нужно будет попобовать.

M>Я вот вчитался сегодня с утра. По-моему там какой-то немного другой барьер. Так ничего чётко Адамс не сакзал.


Естественно другой. Это hardware write barrier. Нужен для того, чтобы кэшы синхронизировать и делать flush processor pipeline, например.

А в начале речь шла о barrier как о технике применяемой в generational GCs, которая помогает разделять generations.

M>Вообще впервые узнал, что в C# есть слово "volatile".


Есть. volatile в C# работает почти как в C++, только в добавление чтение volatile переменных имеет acquire semantics, а запись — release semantics. Очень полезно, когда процессор может производить изменение порядка чтения/записи в память (reads & writes reordering).

Пара ссылок по этой теме:
http://discuss.develop.com/archives/wa.exe?A2=ind0203B&amp;L=DOTNET&amp;P=R375
http://blogs.msdn.com/cbrumme/archive/2003/05/17/51445.aspx
Re[6]: Каков механизм write barrier
От: Блудов Павел Россия  
Дата: 31.05.04 05:40
Оценка: 27 (1)
Здравствуйте, Дарней, Вы писали:

Д>почему мусор? ИМХО, там должен быть 0 — поскольку сброс кэша еще не выполнен, а Singleton.value тоже находится в нем\]


Конечно, там не мусор. Другое дело, что конструктор Singleton'а тоже может что-то писать в память.
И тут-то начинается чехарда. В IA32, где Strong Memory Model все нормально.

У IA64 (и CRL) все плохо — Weak Memory Model, т.е процессор _не_обязан_ класть в память сначала
переменные, проинициализированные в конструкторе Singleton'а, а потом его самого. Пример:

 public Singleton {
     this.str = new string("blabla");
 }
 public static Singleton Value {
    get {
        if (Singleton.value == null) {
            lock (syncRoot) {
                if (Singleton.value == null) {
                    Singleton newVal = new Singleton();
                    Singleton.value = newVal;
                }
            }
        }
        return Singleton.value;
    }
}


Тут у IA64 в какой-то момент времени Singleton.value уже перешел из кеша процессора в память,
а Singleton.str еще null!!! Хотя конструктор уже отработал
Такое может произойти, если
1. Процессоров больше чем один
2. Singleton.value и Singleton.str окажутся в разных страницах памяти.
3. Со страницей памяти Singleton.str работает другой процессор.

Вот этот самый другой процессор может словить Singleton.value != null и Singleton.str == null.

Д>есть немаленькая вероятность, что будет выделено несколько объектов singleton (по одному на каждый процессор )

Нулевая. Ну-ле-ва-я. Об этом позаботится

            lock (syncRoot) {
                        }
[c#]

Замечу, что если переписать код вот так:

[c#]
 public static Singleton Value {
    get {
        lock (syncRoot) {
            if (Singleton.value == null) {
                Singleton newVal = new Singleton();
                Singleton.value = newVal;
            }
        }
        return Singleton.value;
    }
}


То все будет очень даже корректно и для IA64 и для IA32.

Павел.
P.S. Еще вопросы?
... << RSDN@Home 1.1.3 beta 2 >>
Re[6]: Каков механизм write barrier
От: alexkro  
Дата: 31.05.04 19:03
Оценка: 27 (1)
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, alexkro, Вы писали:


A>>Допустим, делается так как ты предлагаешь. Тогда есть следующий вариант развития событий: первый поток входит в lock выделяет Singleton и инициализирует Singleton.value, но замещается вторым потоком прям перед вызовом MemoryBarrier(). Второй поток проверяет Singleton.value, его значение уже не null, и оно тут-же возвращается из функции. Далее второй поток пытается использовать тот объект Singleton, который он получил, но так как сконструированный объект Singleton еще находится в кэше первого потока (пусть эти потоки выполняются на разных процессорах), то второй поток, думая, что он обращается к памяти Singleton'а, на самом деле читает память, в которой еще мусор. Вот так.


Д>почему мусор? ИМХО, там должен быть 0 — поскольку сброс кэша еще не выполнен, а Singleton.value тоже находится в нем


Ты не понял модель памяти CLR. Запись в память для переменных, доступных глобально, является release. Значит присвоение Singleton.value сразу видимо для всех потоков. А вот сам объект — нет. Это я и имею в виду. На месте объекта для другого потока ещё сырая память — мусор.

Д>а в оригинальном варианте есть немаленькая вероятность, что будет выделено несколько объектов singleton (по одному на каждый процессор )


Нет. В оригинальном варианте тот же самый случай: Singleton.value проинициализирован, а сам объект — нет.
Re[10]: Каков механизм write barrier
От: alexkro  
Дата: 01.06.04 09:58
Оценка: 24 (1)
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, alexkro, Вы писали:


A>>lock(syncRoot) — это full fence. Все кэши в этом месте синхронизируются, и никаких read/write reordering не может произойти.


Д>всё-таки не понял. А зачем тогда MemoryBarrier вызывать?


Это из другой оперы. Твоя логика была следующей:
1. Singleton.value == null -- true (Singleton.value in cache of another proc, not sync'd)
2. lock(syncRoot)
3. Singleton.value == null -- true (Singleton.value still in cache not sync'd)

Так вот, третье неверно. lock засинхронизирует кэш для данного потока (на данном процессоре) так, что Singleton.value получит текущее значение. Вообще, оно даже и на шаге 1 будет иметь текущее значение вследствие того, что запись в переменные, видимые глобально, является release, так же, как и запись в volatile переменные (а с volatile, как ты понимаешь, вообще всё без memory barrier работает).

Вообще размышлять в терминах кэшей и их синхронизации не есть продуктивно. Лучше принять модель перегруппировки операций чтения/записи, описанную http://discuss.develop.com/archives/wa.exe?A2=ind0203B&amp;L=DOTNET&amp;P=R375
Re[9]: Каков механизм write barrier
От: Малич Юрий Германия http://malich.ru
Дата: 01.06.04 07:09
Оценка: 18 (1)
Здравствуйте, Блудов Павел, Вы писали:

БП>

Normal loads and stores can be freely reordered, as seen by other CPUs.


БП>Я из этого сделал вывод, что JIT-компилятор для IA64 может гонерить код, выполняя

БП>который IA64 процессоры будут писать в память в удобном им порадке.

Хотелось бы расставить точки над i. Процессоры Itanium 2 никогда не выпоняют ни аппаратного реодеринга чтения и записи в память, ни вообще как-либо операций реордеринга. "The Itanium 2 processor hardware makes no attempt to reorder instructions to avoid stalls.". (На всякий случай отправляю к документу 25111002.pdf "Intel® Itanium® 2 Processor Reference Manual"). Все операции спекуляции выполняются только посредством программного кода (концепция EPIC). Поэтому, если и происходит какое-либо видимое со стороны другого процессора переупорядочивание чтение и записи, то только потому что такой код сгенерировал JIT: а именно "The family of instructions composed of ld.a/ldf.a/ldfp.a, ld.c/ldf.c/ldfp.c, and chk.a provide the capability to dynamically disambiguate memory addresses between loads and stores."
"Практика — критерий истины" (c) Маркс
Re[4]: Каков механизм write barrier
От: Andre Украина  
Дата: 14.05.04 12:50
Оценка: 16 (1)
M>Я вот вчитался сегодня с утра. По-моему там какой-то немного другой барьер. Так ничего чётко Адамс не сакзал.

Nvf в комментариях куча ссылок на статьи различные проскакивала.

M>Вообще впервые узнал, что в C# есть слово "volatile".


... << RSDN@Home 1.1.3 beta 2 >> :: L Fudge — Love Letters Feat Jasmin
Я бы изменил мир — но Бог не даёт исходников...
Re[2]: Каков механизм write barrier
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 11.05.04 10:22
Оценка: 15 (1)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Serginio1, Вы писали:


VD>Я вот тоже слышал этот термин несклько раз, но он как-то упоминается в сколь. Типа "обсуждение этой фичи выходит за рамки...".


Интересно что, при инлайне тормозов нет (веренее есть но только в 2 раза по ставнению с int)


public class IntClass
    { 
      public int value;
          public IntClass(int val)
          {
              value = val;
          }
    }




    public static void Run8(System.Windows.Forms.TextBox _log, int Count)
        {
            _log.AppendText("Сортировка вставка IntClass массива Count=" + Count.ToString() + Environment.NewLine);

            Utils.PerfCounter timer = new PerfCounter();
            int r = 666;
            IntClass[] IntClassArray = new IntClass[Count];
            IntClass[] IntClassArray1 = new IntClass[Count];

            while (r < 666000)
            {
                IntRandim F = new IntRandim(r, 0, Count);

                timer.Start();
                for (int i = 0; i < Count; i++)
                {
                    IntClassArray1[i] = new IntClass(i);
                    
                }

                // перемешаем массив
                for (int i = 0; i < Count; i++)
                {
                    int temp = F.Next();
                    int temp2 = F.Next();
                    IntClass temp3 = IntClassArray1[temp];

                    IntClassArray1[temp] = IntClassArray1[temp2];
                    IntClassArray1[temp2] = temp3;
                }

                // сортировка вставками

                IntClassArray[0] = IntClassArray1[0];
                
                    for (int i = 1; i < Count; i++)
                    {
                        Int32 L = 0;
                        Int32 R = i-1;
                        IntClass Current=IntClassArray1[i];
                        int key = Current.value;
                        //int key = IntClassArray1[i].value;

                    while (L < R)
                        {
                            int Midl = (L + R) >>1;

                            if (IntClassArray[Midl].value <= key)
                                L = Midl + 1;
                            else
                                R = Midl;
                        }

                                                

                        for (int j = i; j > L; j--)
                            IntClassArray[j] = IntClassArray[j - 1];

                        IntClassArray[L] = IntClassArray1[i];
                    
                    }
                
                _log.AppendText(string.Format(" Время={0}" + Environment.NewLine, timer.Finish()));
                for (int i = 1; i < Count; i++)
                    if (IntClassArray[i].value != i)
                    {
                        _log.AppendText(string.Format(" i={0} <> {1}", i, IntClassArray[i].value));
                        return;
                    }

                r *= 10;
            }
        }



Но такой вариант безбожно тормозит пропорционально квадрату занимаемой памяти с применением Add3.

 public class Int32AsObjectInsertSort
    {
        public IntClass[] ar;
        public Int32 count;
        private Int32 temp;
        private Int32 Midl;
        public Int32AsObjectInsertSort(Int32 Size)
        {
            ar = new IntClass[Size];
            count = 0;
        }
        private Int32 ПоискПоловиннымДелением(Int32 key)
        {
            Int32 i = 0;
            Int32 j = count - 1;

            while (i <= j)
            {
                Midl = (i + j) >>1;
                if (ar[Midl].value > key) { j = Midl - 1; }
                else if (ar[Midl].value < key) { i = Midl + 1; }
                else { return i; }
            }

            return i;
        }

        public void Add3(IntClass value)
        {
            if (count == 0)
            {
                count = 1;
                ar[0] = value;
            }
            else
            {
                Int32 index = ПоискПоловиннымДелением(value.value);

                for (Int32 i = count; i > index; i--)
                {
                    ar[i] = ar[i - 1];
                }

                ar[index] = value;
                count++;
            }
        }
    }
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[3]: Каков механизм write barrier
От: mihailik Украина  
Дата: 14.05.04 12:42
Оценка: +1
M>>volatile and MemoryBarrier() Brad Adams Blog
S> Спасибо. Нужно будет попобовать.

Я вот вчитался сегодня с утра. По-моему там какой-то немного другой барьер. Так ничего чётко Адамс не сакзал.

Вообще впервые узнал, что в C# есть слово "volatile".
... << RSDN@Home 1.1.3 stable >>
Re: Каков механизм write barrier
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.05.04 16:57
Оценка:
Здравствуйте, Serginio1, Вы писали:

Я вот тоже слышал этот термин несклько раз, но он как-то упоминается в сколь. Типа "обсуждение этой фичи выходит за рамки...".
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Каков механизм write barrier
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 14.05.04 09:19
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Ещё немного из свежего блога:


M>volatile and MemoryBarrier() Brad Adams Blog

Спасибо. Нужно будет попобовать.
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[5]: Каков механизм write barrier
От: mihailik Украина  
Дата: 14.05.04 12:53
Оценка:
A>Nvf в комментариях куча ссылок на статьи различные проскакивала.

О, а я комментарии обычно не читаю. Значит нужно читать!
... << RSDN@Home 1.1.3 stable >>
Re[3]: Каков механизм write barrier
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 18.05.04 14:00
Оценка:
Здравствуйте, Serginio1, Вы писали:

Кстати дома то у меня видби и эти два варианта отрабатывают по разному, на работе провел тест с 1.1 картина и отрабатывают одинаково.
В видби они кое что подправили.
Интересно этот же тест прогнать на 2005.
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[4]: Каков механизм write barrier
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.05.04 20:44
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S> Кстати дома то у меня видби и эти два варианта отрабатывают по разному, на работе провел тест с 1.1 картина и отрабатывают одинаково.

S> В видби они кое что подправили.
S> Интересно этот же тест прогнать на 2005.

А в чем разница?
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Каков механизм write barrier
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 19.05.04 09:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Serginio1, Вы писали:


S>>Здравствуйте, Serginio1, Вы писали:


S>> Кстати дома то у меня видби и эти два варианта отрабатывают по разному, на работе провел тест с 1.1 картина и отрабатывают одинаково.

S>> В видби они кое что подправили.
S>> Интересно этот же тест прогнать на 2005.

VD>А в чем разница?

Разница в том, что в 1.1 эти два алгоритма отрабатывают одинаково, то есть сортировка в одной процедуре и сортировка через добавление (Int32AsObjectInsertSort.Add3)
и writw barier и в обоих случаях.
В видби сортировка в в процедуре в 2 раза медленне чем на интах , но стабильно, при сортировке Int32AsObjectInsertSort.Add3 write barier остается и геометрическая прогрессия замедления от размера данных как в 1.1
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[3]: Каков механизм write barrier
От: kkav Россия  
Дата: 21.05.04 08:06
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, mihailik, Вы писали:


M>>Ещё немного из свежего блога:


M>>volatile and MemoryBarrier() Brad Adams Blog

S> Спасибо. Нужно будет попобовать.

По указанной ссылке написано:
 public static Singleton Value {
    get {
        if (Singleton.value == null) {
            lock (syncRoot) {
                if (Singleton.value == null) {
                    Singleton newVal = new Singleton();
                    // Insure all writes used to construct new value have been flushed. 
                    System.Threading.Thread.MemoryBarrier(); 
                    Singleton.value = newVal;         // publish the new value 
                }
            }
        }
        return Singleton.value;
    }
}


Почему System.Threading.Thread.MemoryBarrier();
Выполняется до Singleton.value = newVal;
а не после него, если мы боимся, что к моменту выполнения
другим потоком (lock (syncRoot) { if (Singleton.value == null) ...)
Singleton.value еще не будет еще присвоено?
Не логичнее ли высвободить кэш после присвоения?
... << RSDN@Home 1.1.3 beta 2 >>
Re[4]: Каков механизм write barrier
От: alexkro  
Дата: 21.05.04 09:26
Оценка:
Здравствуйте, kkav, Вы писали:

K>Здравствуйте, Serginio1, Вы писали:


S>>Здравствуйте, mihailik, Вы писали:


M>>>Ещё немного из свежего блога:


M>>>volatile and MemoryBarrier() Brad Adams Blog

S>> Спасибо. Нужно будет попобовать.

K>По указанной ссылке написано:

K>
K> public static Singleton Value {
K>    get {
K>        if (Singleton.value == null) {
K>            lock (syncRoot) {
K>                if (Singleton.value == null) {
K>                    Singleton newVal = new Singleton();
K>                    // Insure all writes used to construct new value have been flushed. 
K>                    System.Threading.Thread.MemoryBarrier(); 
K>                    Singleton.value = newVal;         // publish the new value 
K>                }
K>            }
K>        }
K>        return Singleton.value;
K>    }
K>}      
K>


Там в одном из комментариев более правильная версия есть с двумя memory barriers.

K>Почему System.Threading.Thread.MemoryBarrier();

K>Выполняется до Singleton.value = newVal;
K>а не после него, если мы боимся, что к моменту выполнения
K>другим потоком (lock (syncRoot) { if (Singleton.value == null) ...)
K>Singleton.value еще не будет еще присвоено?
K>Не логичнее ли высвободить кэш после присвоения?

Допустим, делается так как ты предлагаешь. Тогда есть следующий вариант развития событий: первый поток входит в lock выделяет Singleton и инициализирует Singleton.value, но замещается вторым потоком прям перед вызовом MemoryBarrier(). Второй поток проверяет Singleton.value, его значение уже не null, и оно тут-же возвращается из функции. Далее второй поток пытается использовать тот объект Singleton, который он получил, но так как сконструированный объект Singleton еще находится в кэше первого потока (пусть эти потоки выполняются на разных процессорах), то второй поток, думая, что он обращается к памяти Singleton'а, на самом деле читает память, в которой еще мусор. Вот так.

Вопрос этот вообщем очень интересный. Почитай пост Vance Morrison'а (ссылка в блоге Брада) про моделирование поведения памяти с помощью перестановок чтения/записи. А так же про модель памяти CLR в блоге Chris Brumme'а.
Re[5]: Каков механизм write barrier
От: Дарней Россия  
Дата: 31.05.04 04:09
Оценка:
Здравствуйте, alexkro, Вы писали:

A>Допустим, делается так как ты предлагаешь. Тогда есть следующий вариант развития событий: первый поток входит в lock выделяет Singleton и инициализирует Singleton.value, но замещается вторым потоком прям перед вызовом MemoryBarrier(). Второй поток проверяет Singleton.value, его значение уже не null, и оно тут-же возвращается из функции. Далее второй поток пытается использовать тот объект Singleton, который он получил, но так как сконструированный объект Singleton еще находится в кэше первого потока (пусть эти потоки выполняются на разных процессорах), то второй поток, думая, что он обращается к памяти Singleton'а, на самом деле читает память, в которой еще мусор. Вот так.


почему мусор? ИМХО, там должен быть 0 — поскольку сброс кэша еще не выполнен, а Singleton.value тоже находится в нем
а в оригинальном варианте есть немаленькая вероятность, что будет выделено несколько объектов singleton (по одному на каждый процессор )
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[7]: Каков механизм write barrier
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.05.04 06:44
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Замечу, что если переписать код вот так:


БП>
БП> public static Singleton Value {
БП>    get {
БП>        lock (syncRoot) {
БП>            if (Singleton.value == null) {
БП>                Singleton newVal = new Singleton();
БП>                Singleton.value = newVal;
БП>            }
БП>        }
БП>        return Singleton.value;
БП>    }
БП>}
БП>


БП>То все будет очень даже корректно и для IA64 и для IA32.


Вот только сильно медленнее.
... << RSDN@Home 1.1.4 beta 1 >>
AVK Blog
Re[7]: Каков механизм write barrier
От: alexkro  
Дата: 31.05.04 19:11
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>И тут-то начинается чехарда. В IA32, где Strong Memory Model все нормально.


Не тут то было. Strong memory model для одного процессора. А если у тебя их восемь: по четыре в hemisphere? Тут-то синхронизация кэшей начинает играть ту же роль, что и перестановка чтения/записи.

БП>У IA64 (и CRL) все плохо — Weak Memory Model, т.е процессор _не_обязан_ класть в память сначала


У CLR есть своя модель памяти. На IA64 она не будет weak.
Re[8]: Каков механизм write barrier
От: Блудов Павел Россия  
Дата: 01.06.04 06:18
Оценка:
Здравствуйте, alexkro, Вы писали:

A>У CLR есть своя модель памяти. На IA64 она не будет weak.


Тогда я чего-то недопонял. Вот тут написано

http://blogs.msdn.com/cbrumme/archive/2003/05/17/51445.aspx

IA64 specifies a weaker memory model than X86. Specifically, all loads and stores are normal loads and stores. The application must use special ld.acq and st.rel instructions to achieve acquire and release semantics.


и тут же

In fact, the CLR has done exactly the same thing. Section 12.6 of Partition I of the ECMA CLI specification explains our memory model. This explains the alignment rules, byte ordering, the atomicity of loads and stores, volatile semantics, locking behavior, etc. According to that specification, an application must use volatile loads and volatile stores to achieve acquire and release semantics. Normal loads and stores can be freely reordered, as seen by other CPUs.


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

Павел.
... << RSDN@Home 1.1.3 beta 2 >>
Re[7]: Каков механизм write barrier
От: Дарней Россия  
Дата: 01.06.04 07:12
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Нулевая. Ну-ле-ва-я. Об этом позаботится


поправь меня, если я ошибаюсь.
к моменту, когда завершится вот этот код:
        public static Singleton Value 
        {
            get 
            {
                if (Singleton.value == null) 
                {
                    lock (syncRoot) 
                    {
                        if (Singleton.value == null) 
                        {
                            Singleton newVal = new Singleton();
                            // Insure all writes used to construct new value have been flushed. 
                            System.Threading.Thread.MemoryBarrier(); 
                            Singleton.value = newVal;         // publish the new value 
                        }
                    }
                }
                return Singleton.value;
            }
        }

обновленное значение Singleton.value будет находиться в кэше процессора, в основную память оно будет сброшено позднее. В этот момент поток на другом процессоре может попытаться получить это значение, вызовется getter. Поскольку Singleton.value для него еще равен null, он создаст новый объект Singleton и запишет его в Singleton.value — в свою копию. (Поскольку на другом потоке геттер уже завершился, он вполне благополучно зайдет в lock).
И в результате мы получим две разные копии Singleton.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[9]: Каков механизм write barrier
От: alexkro  
Дата: 01.06.04 07:39
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Здравствуйте, alexkro, Вы писали:


A>>У CLR есть своя модель памяти. На IA64 она не будет weak.


БП>Тогда я чего-то недопонял. Вот тут написано


БП>http://blogs.msdn.com/cbrumme/archive/2003/05/17/51445.aspx


...

БП>Я из этого сделал вывод, что JIT-компилятор для IA64 может гонерить код, выполняя

БП>который IA64 процессоры будут писать в память в удобном им порадке.

А после этого описывается реальная модель памяти майкрософтовской реализации CLR, которая гораздо более strong, чем спецификация ECMA CLI, а также предпологается, что следующия версия стандарта ECMA CLI будет следовать этой модели.
Re[8]: Каков механизм write barrier
От: alexkro  
Дата: 01.06.04 07:47
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, Блудов Павел, Вы писали:


БП>>Нулевая. Ну-ле-ва-я. Об этом позаботится


Д>поправь меня, если я ошибаюсь.

Д>обновленное значение Singleton.value будет находиться в кэше процессора, в основную память оно будет сброшено позднее. В этот момент поток на другом процессоре может попытаться получить это значение, вызовется getter. Поскольку Singleton.value для него еще равен null,

lock(syncRoot) — это full fence. Все кэши в этом месте синхронизируются, и никаких read/write reordering не может произойти.

>он создаст новый объект Singleton и запишет его в Singleton.value — в свою копию. (Поскольку на другом потоке геттер уже завершился, он вполне благополучно зайдет в lock).

Д>И в результате мы получим две разные копии Singleton.
Re[9]: Каков механизм write barrier
От: Дарней Россия  
Дата: 01.06.04 08:36
Оценка:
Здравствуйте, alexkro, Вы писали:

A>lock(syncRoot) — это full fence. Все кэши в этом месте синхронизируются, и никаких read/write reordering не может произойти.


то есть он синхронизирует полностью всё содержимое всех кэшей?
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[9]: Каков механизм write barrier
От: Дарней Россия  
Дата: 01.06.04 08:50
Оценка:
Здравствуйте, alexkro, Вы писали:

A>lock(syncRoot) — это full fence. Все кэши в этом месте синхронизируются, и никаких read/write reordering не может произойти.


всё-таки не понял. А зачем тогда MemoryBarrier вызывать?
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[10]: Каков механизм write barrier
От: Блудов Павел Россия  
Дата: 01.06.04 09:55
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>всё-таки не понял. А зачем тогда MemoryBarrier вызывать?


Затем, что (читайте выше) Singleton.value может быть уже не null
и другой процессор уже может попытаться его исползовать. В этом
случае

lock(syncRoot)

НЕ ПРОИСХОДИТ. Так вот, для того, чтобы Singleton.value был отправлен
в память __последним__ а не каким-то, нужно и сбросить кеш.
Раньше это называли FlushProcessorCache. А теперь Memory barrier.

Павел.
... << RSDN@Home 1.1.3 beta 2 >>
Re[10]: Каков механизм write barrier
От: Блудов Павел Россия  
Дата: 01.06.04 10:01
Оценка:
Здравствуйте, alexkro, Вы писали:

A>А после этого описывается реальная модель памяти майкрософтовской реализации CLR, которая гораздо более strong, чем спецификация ECMA CLI

Это я читал. А в начале сказано, что вся эта дисскуссия всплыла из-за того, что на каком-то
32-головом IA64 при массивном стресс-тесте как раз и произошло что описано выше.

A>, а также предпологается, что следующия версия стандарта ECMA CLI будет следовать этой модели.


Это я тоже читал. Будем подождать. А то действительно получается что все конечно быстро
и круто, только программировать для таких процессоров должны не люди.
Павел.
... << RSDN@Home 1.1.3 beta 2 >>
Re[12]: Каков механизм write barrier
От: Блудов Павел Россия  
Дата: 02.06.04 01:12
Оценка:
Здравствуйте, alexkro, Вы писали:

<все почикано>

Мда.... Действительно, два.

Чем больше я об этом думаю, тем больше убеждаюсь,
что старую добрую двойную проверку настоятельно
будут рекомендовать к использованию в очень
исключительных случаях. Потому как два барьера
уже приводят фактически к lock(syncRoot) — разница
настолько мала, что овчинка перестает стоить
выделки.

Павел.
... << RSDN@Home 1.1.3 beta 2 >>
Re[10]: Каков механизм write barrier
От: bw  
Дата: 23.06.04 15:46
Оценка:
Здравствуйте, Малич Юрий, Вы писали:


МЮ>Хотелось бы расставить точки над i. Процессоры Itanium 2 никогда не выпоняют ни аппаратного реодеринга чтения и записи в память, ни вообще как-либо операций реордеринга. "The Itanium 2 processor hardware makes no attempt to reorder instructions to avoid stalls.". (На всякий случай отправляю к документу 25111002.pdf "Intel® Itanium® 2 Processor Reference Manual"). Все операции спекуляции выполняются только посредством программного кода (концепция EPIC).


В спецификации на Itanium (245317.pdf) memory access reodering идет полным ходом.В мане по Itanium2 (пунт 1.1) сказано, что он удовлетворяет специфицации Itanium architecture, за исключением явно указанных ограничений, среди которых идет упомяунтый instruction reodering.

Отказа от memory access reodering в 25111002.pdf я не видел. Напротив,пункт 6.7.5 из 25111002.pdf косвенно указывает
на присутствие реодеринга в Itanium2.
Re[11]: Каков механизм write barrier
От: Дарней Россия  
Дата: 23.07.04 11:02
Оценка:
Здравствуйте, alexkro, Вы писали:

A>Так вот, третье неверно. lock засинхронизирует кэш для данного потока (на данном процессоре) так, что Singleton.value получит текущее значение.


всё-таки меня сомнения грызут. А где можно про это прочитать?

A>Вообще, оно даже и на шаге 1 будет иметь текущее значение вследствие того, что запись в переменные, видимые глобально, является release, так же, как и запись в volatile переменные (а с volatile, как ты понимаешь, вообще всё без memory barrier работает).


странно — в MSDN написано, что acquire/release поддерживается для volatile, а вот про static ничего такого не написано.

Блин, ничего толком понять не могу
И всё-таки, чем им вариант с volatile не понравился?
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[10]: Каков механизм write barrier
От: Дарней Россия  
Дата: 23.07.04 11:47
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>всё-таки не понял. А зачем тогда MemoryBarrier вызывать?


кажется, до меня дошло! :idea:
это нужно на тот случай, если планировщик остановит тред после Singleton.value = newVal, но до выхода из блока lock
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[11]: Каков механизм write barrier
От: Дарней Россия  
Дата: 26.07.04 06:55
Оценка:
Здравствуйте, alexkro, Вы писали:

A>запись в переменные, видимые глобально, является release, так же, как и запись в volatile переменные (а с volatile, как ты понимаешь, вообще всё без memory barrier работает).


вот например тоже. про volatile написано, а про "просто" глобальные переменные — ни слова.

In
particular, however, the compiler will not move memory reads before a lock
aquire (or a volatile read), and will not move memory writes after a lock
release (or a volatile write), and will respect the MemoryBarrier APIs.

Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[11]: Каков механизм write barrier
От: Малич Юрий Германия http://malich.ru
Дата: 27.07.04 08:31
Оценка:
Здравствуйте, bw, Вы писали:

bw>В спецификации на Itanium (245317.pdf) memory access reodering идет полным ходом.В мане по Itanium2 (пунт 1.1) сказано, что он удовлетворяет специфицации Itanium architecture, за исключением явно указанных ограничений, среди которых идет упомяунтый instruction reodering.


bw>Отказа от memory access reodering в 25111002.pdf я не видел. Напротив,пункт 6.7.5 из 25111002.pdf косвенно указывает

bw>на присутствие реодеринга в Itanium2.

Да, спасибо. Судя по всему реордеринг может происходить (245317.pdf, section 4.4.7), но не из-за динамического планировщика, которого нет, а из-за доступности данных на разных уровнях иерархии памяти.
"Практика — критерий истины" (c) Маркс
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.