Re[2]: Многопоточность
От: MadHuman Россия  
Дата: 24.12.20 08:59
Оценка: 7 (1)
Здравствуйте, VladD2, Вы писали:

_NN>>Не нужен ли где-нибудь volatile, Volatile.Read или Interlocked.Read ?


VD>В общем, случае — нет. Но в CompareExchange происходит мемори борьер и если читать после него в том же потоке, то все будет ОК. Дучше добавить к _disposed volatile. Только это не про атомарность, а про сброс кэшей процессоров.

дак volatile вынуждает компилятор при генерации кода только всегда читать филд из памяти (запрещая генерировть код так чтоб результат 1-го чтения закэшировать в регистре например и затем реюзать) или ещё добавляет какую-то спец инструкцию перед чтением из памяти чтоб кэши процессора сбрасывать?
разве когерентность кэшей не обеспечивается аппаратно?
иначе существует вероятность при чтении из памяти получать не актуальное значение (которое из локального кэша ядра прочтётся), это действительно так?
Re[3]: Многопоточность
От: Sharov Россия  
Дата: 24.12.20 10:12
Оценка:
Здравствуйте, MadHuman, Вы писали:

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


_NN>>>Не нужен ли где-нибудь volatile, Volatile.Read или Interlocked.Read ?


VD>>В общем, случае — нет. Но в CompareExchange происходит мемори борьер и если читать после него в том же потоке, то все будет ОК. Дучше добавить к _disposed volatile. Только это не про атомарность, а про сброс кэшей процессоров.

MH>дак volatile вынуждает компилятор при генерации кода только всегда читать филд из памяти (запрещая генерировть код так чтоб результат 1-го чтения закэшировать в регистре например и затем реюзать) или ещё добавляет какую-то спец инструкцию перед чтением из памяти чтоб кэши процессора сбрасывать?

А в чем проблема запретить любые манипуляции с этим полем (перестановки в целях оптимизации) и выставлять инструкции
чтения из памяти, а не из регистра? Т.е. вообще не генерировать код чтения поля из регистра.

MH>разве когерентность кэшей не обеспечивается аппаратно?


Именно железо.

MH>иначе существует вероятность при чтении из памяти получать не актуальное значение (которое из локального кэша ядра прочтётся), это действительно так?


По идее нет, но у процессора столько оптимизаций на счет работы с памятью, что сразу и не скажешь. На этот счет
надо читать Memory model соотв. runtime'а и смотреть какие гарантии он дает. Т.е. ответ на этот вопрос должен дать
этот документ.

Хотя стоп, если кто-то записал новое значение, но его еще не отправил -- процессор попридержал в целях оптимизации, то
возможно, с другой стороны, новое значение должно отразиться на кэше, соотв. если кто-то будет читать из кэша, то
прочитает новое значение, тот кто отправился в RAM -- не судьба...
Кодом людям нужно помогать!
Re[3]: Многопоточность
От: Ночной Смотрящий Россия  
Дата: 24.12.20 12:06
Оценка: +1
Здравствуйте, MadHuman, Вы писали:

MH>разве когерентность кэшей не обеспечивается аппаратно?


В х86 — да. С ARM все несколько сложнее.

volatile, если говорить формально, просто говорит о том что переменную будут читать и писать из разных потоков. А что сделает компилятор, рантайм и железо — зависит от конкретной реализации. И там на любом уровне может быть отличие — и запрет кешировать переменную в регистре, и запрет перестановки инструкций, и добавление барьера, и т.п.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: Многопоточность
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.12.20 12:25
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>дак volatile вынуждает компилятор при генерации кода только всегда читать филд из памяти (запрещая генерировть код так чтоб результат 1-го чтения закэшировать в регистре например и затем реюзать) или ещё добавляет какую-то спец инструкцию перед чтением из памяти чтоб кэши процессора сбрасывать?

MH>разве когерентность кэшей не обеспечивается аппаратно?

Да, он запрещает переупорядочивание инструкций как компилятором, так и процессором.

MH>иначе существует вероятность при чтении из памяти получать не актуальное значение (которое из локального кэша ядра прочтётся), это действительно так?


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

Тут вот приводили реальный пример приводящий к неожиданному поведению.

using System;
using System.Threading;

class Program
{
    static int a;
    static void Main()
    {
        bool b = true;

        new Thread(() =>
            {
                Thread.Sleep(1000);
                b = false;
            })
        {
            IsBackground = true
        }.Start();

        while (b)
        {
            a++;
            //Thread.MemoryBarrier();
        }

        Console.WriteLine($"b={b} a={a}");
    }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.