Re[2]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 05.04.23 18:00
Оценка: +2
Здравствуйте, fdn721, Вы писали:

F>Ох уж эти объясняторы...


F>На самом деле ни кто ни чего не переупорядочивает.


На самом деле переупорядочивает. В Pentium-Pro появился буфер переупорядочивания, тогда ещё размером в 40 мопов и теперь он решает в каком порядке выполнять мопы, а не ты.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[4]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 05.04.23 18:02
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Ядра не знают про кеши других ядер. Существует некий протокол,...


угу https://ru.wikipedia.org/wiki/MOESI
Всё сказанное выше — личное мнение, если не указано обратное.
Re: Memory barrier не могу понять что это
От: syrompe  
Дата: 05.04.23 18:17
Оценка:
Здравствуйте, dsalodki, Вы писали:

D>Поясните пожалуйста самым простым способом, я гуглю, но что-то не понятно. Толи это позволяет отменить кеширование переменно, толи ещё что-то


Это же форум по .Net.
Atomicity, volatility and immutability are different, part one и еще там два эпизода по ссылкам. (блин, уже 12 лет прошло)

Поправьте где неправ:
1. volatile в С# — какая-то шляпа
2. lock — вроде как ведет к Memory Barier, правда неявно
3. у нас есть Interlocked, которого хватает в 99%
Re[2]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 05.04.23 19:32
Оценка: 12 (1)
Здравствуйте, syrompe, Вы писали:

S>Поправьте где неправ:

S>1. volatile в С# — какая-то шляпа

Нет, оно работает так как должно. Штука очень полезная, особенно если ты шаришь память между между процессами (например с помощью MMF). Например, у тебя выделена память с помощью VirtualAlloc(), в которой ты сделал окно. Ты на неё смотришь через стуктуру (приводишь к указателю на структуру). Все поля этой структуры должны быть volatile — компилятор никогда не сможет угадать, кто и когда поменяет эту память. Фактически это указание компилятору, что к памяти имеет доступ кто-то ещё.

S>2. lock — вроде как ведет к Memory Barier, правда неявно


Да, это так.

S>3. у нас есть Interlocked, которого хватает в 99%

Нет: кому-то хватает, а кому-то нет. Interlocked в конечном счёте выставляет префикс lock на операции обращения к памяти. Это приодит к сигналу Lock на шине процессора при исполнение — производительность на таких штуках серьёзно деградирует.
В принципе любые примитивы синхронизации приводят к деградации производительности. Чем более они высокоуровневые — тем сильнее, хотя с походами в ядро им конечно не сравниться.

Насчёт Interlocked: в циклах ожидания нужно использовать процессорную инструкцию pause, но из C# этого сделать невозможно. Вот пример:

            while (1 == Interlocked.CompareExchange(ref m_dwBusy, 1, 0))
            {
                //здесь должна быть pause
            }


Т.е. я не знаю — по-моему это ещё не ушло в релиз.
Всё сказанное выше — личное мнение, если не указано обратное.
Отредактировано 05.04.2023 19:32 Философ . Предыдущая версия .
Re[3]: Memory barrier не могу понять что это
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.04.23 20:38
Оценка:
Здравствуйте, Философ, Вы писали:

S>>3. у нас есть Interlocked, которого хватает в 99%


Ф>Нет: кому-то хватает, а кому-то нет. Interlocked в конечном счёте выставляет префикс lock на операции обращения к памяти. Это приодит к сигналу Lock на шине процессора при исполнение — производительность на таких штуках серьёзно деградирует.


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

Ф>В принципе любые примитивы синхронизации приводят к деградации производительности. Чем более они высокоуровневые — тем сильнее, хотя с походами в ядро им конечно не сравниться.


Какие высокоуровневые примитивы синхронизации обходятся без походов в ядро?
Re[5]: Memory barrier не могу понять что это
От: Sharowarsheg  
Дата: 06.04.23 00:50
Оценка:
Здравствуйте, paradok, Вы писали:


P>не-е-е-е, если вы намерено не запрограммировали и не выполнили сравнение в другом потоке или нити никогда не будет.


Ну да. Если ты намеренно не запрограммировал это на разных потоках, то барьер не нужен. Вообще, мне кажется, если программировать всё в одном потоке, то вообще можно не знать, что барьеры существуют. По крайней мере, в "обычных" языках и процессорах.
Re[5]: Memory barrier не могу понять что это
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.04.23 02:50
Оценка:
Здравствуйте, Философ, Вы писали:

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


S>>volatile как модификатор переменной — запрет на кэширование. volatile как инструкция — запрет на чтение/запись из кэша в конкретном месте, т.е. немного не о том в общем случае, но в частном (C# и .NET) volatile фактически генерирует вокруг обращений еще и барьеры. В языках, где volatile не генерирует барьеры, проще представить одно без другого.


Ф>volatile в шарпе не генерирует никаких барьеров.

Если так, то с помощью какоюй таблетки обеспечивается семантика, заявленная в спеке C# в общем случае, а не про Intel X86/X64?

A read of a volatile field is called a volatile read. A volatile read has “acquire semantics”; that is, it is guaranteed to occur prior to any references to memory that occur after it in the instruction sequence.
A write of a volatile field is called a volatile write. A volatile write has “release semantics”; that is, it is guaranteed to happen after any memory references prior to the write instruction in the instruction sequence.


Ф>Слово volatile запрещает оптимизации компялитора в отношении поля, например компилятор всегда будет обращаться памяти где лежит эта переменная, не кешируя её в регистре. Ещё: компилятор не исключит обращения к этой переменной при чтении.

Ф>Новое значение в переменную компилятор будет писать там, где это написал программист, а не там где это оказалось удобно компилятору.
Ф>Всё!

Ф>Больше volatile не делает ничего. Барьеры при обращении к нескольким volatile полям по-прежнему нужны.

С оговорками про конкретную платформу — да. А вообще есть другие мнения. А так же указание полного барьера в методах VolatileRead/Write.
Re[6]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 06.04.23 04:50
Оценка:
Здравствуйте, samius, Вы писали:

Ф>>volatile в шарпе не генерирует никаких барьеров.

S>Если так, то с помощью какоюй таблетки обеспечивается семантика, заявленная в спеке C# в общем случае, а не про Intel X86/X64?

с помощью Thread.VolatileRead() и Thread.VolatileWrite()

S>С оговорками про конкретную платформу — да. А вообще есть другие мнения. А так же указание полного барьера в методах VolatileRead/Write.


Фишка в том, что барьеры нужны там где они нужны: там где есть опасность перестановок — нужны, там где пофиг — не нужны.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[4]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 06.04.23 04:58
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Чтобы почувствовать эту "серьезную деградацию", на современном железе нужно дергать эти операции с частотой хотя бы в сотни тысяч, а лучше — миллионы раз в секунду.


И тем не менее достичь этого легко: даже Thread.SpinWait(Int32) используется частенько. Достичь 100К итераций ожидания не так сложно как тебе кажется.

ЕМ>Какие высокоуровневые примитивы синхронизации обходятся без походов в ядро?


Ну например SpinLock, ну а если повезёт, то например ManualResetEventSlim тоже может на ожидании без походов в ядро обойтись.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[7]: Memory barrier не могу понять что это
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.04.23 05:28
Оценка:
Здравствуйте, Философ, Вы писали:

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


Ф>>>volatile в шарпе не генерирует никаких барьеров.

S>>Если так, то с помощью какоюй таблетки обеспечивается семантика, заявленная в спеке C# в общем случае, а не про Intel X86/X64?

Ф>с помощью Thread.VolatileRead() и Thread.VolatileWrite()

Разумеется, работа с volatile полями не приводит к задействованию этих методов. И, прямо в документации по предъявленным ссылкам, написано, что барьеры вставляются при необходимости.

S>>С оговорками про конкретную платформу — да. А вообще есть другие мнения. А так же указание полного барьера в методах VolatileRead/Write.


Ф>Фишка в том, что барьеры нужны там где они нужны: там где есть опасность перестановок — нужны, там где пофиг — не нужны.

А разве кто-то утверждал обратное? Что они не нужны там, где нужны и нужны там, где не нужны?
Re[8]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 06.04.23 06:13
Оценка:
Здравствуйте, samius, Вы писали:

S>...И, прямо в документации по предъявленным ссылкам, написано, что барьеры вставляются при необходимости.


А в коде BCL написано что, там безусловно вставляется барьер, без всяких "по необходимости". Сходи и посмотри.

S>А разве кто-то утверждал обратное? Что они не нужны там, где нужны и нужны там, где не нужны?


В этой теме кто-то говорил, что для volatile полей генерируются барьеры. На деле же барьеры ты должен вставлять сам.
Всё сказанное выше — личное мнение, если не указано обратное.
Отредактировано 06.04.2023 6:18 Философ . Предыдущая версия .
Re[9]: Memory barrier не могу понять что это
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.04.23 06:18
Оценка:
Здравствуйте, Философ, Вы писали:

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


S>>...И, прямо в документации по предъявленным ссылкам, написано, что барьеры вставляются при необходимости.


Ф>А в коде BCL написано что, там безусловно вставляется барьер, без всяких "по необходимости". Сходи и посмотри.

Я об этом пару сообщений назад написал.
Re[4]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 06.04.23 06:27
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Какие высокоуровневые примитивы синхронизации обходятся без походов в ядро?


Сейчас глянул сорцы CLR — Monitor.Enter() в конечном счёте тоже может без походов в ядро обойтись.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[5]: Memory barrier не могу понять что это
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.04.23 07:56
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>И тем не менее достичь этого легко: даже Thread.SpinWait(Int32) используется частенько. Достичь 100К итераций ожидания не так сложно как тебе кажется.


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

ЕМ>>Какие высокоуровневые примитивы синхронизации обходятся без походов в ядро?


Ф>Ну например SpinLock


Он только с виду "высокоуровневый". Внутри там примитивный цикл из InterlockedCompareExchange (которая раскрывается в команду CmpXchg), InterlockedIncrement/InterlockedDecrement (которые раскрываются в lock xadd), или чего-то подобного. Реально же высокоуровневые примитивы, подразумевающие ожидание с переключением потоков, без походов в ядро не реализуемы.

Ф>если повезёт, то например ManualResetEventSlim тоже может на ожидании без походов в ядро обойтись.


И это на той же технике, как и критические секции со spin count. Как раз костыли для тех, кто их использует бездумно, "по учебнику".
Re[5]: Memory barrier не могу понять что это
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.04.23 07:58
Оценка:
Здравствуйте, Философ, Вы писали:

ЕМ>>Какие высокоуровневые примитивы синхронизации обходятся без походов в ядро?


Ф>Сейчас глянул сорцы CLR — Monitor.Enter() в конечном счёте тоже может без походов в ядро обойтись.


Из каких соображений Вы причисляете такие средства к "высокоуровневым"?
Re[6]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 06.04.23 08:29
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Из каких соображений Вы причисляете такие средства к "высокоуровневым"?


Из тех соображений, что иногда синхронизация делается вообще без каких-либо примитивов, пример рукопашной синхронизации.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[7]: Memory barrier не могу понять что это
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.04.23 09:21
Оценка:
Здравствуйте, Философ, Вы писали:

ЕМ>>Из каких соображений Вы причисляете такие средства к "высокоуровневым"?


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


То есть, если программа использует InterlockedCompareExchange, что фактически просто вставляет команду CmpXchg, то это "низкоуровневое" средство, а если вызывает некую библиотечную функцию, в которую завернута та же команда, то средство враз становится "высокоуровневым"?
Re[8]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 06.04.23 09:36
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>То есть, если программа использует InterlockedCompareExchange, что фактически просто вставляет команду CmpXchg, то это "низкоуровневое" средство, а если вызывает некую библиотечную функцию, в которую завернута та же команда, то средство враз становится "высокоуровневым"?


Ну в общем-то да: даже ReaderWriterLock в конечном счёте ведёт к CompareExchange.

Признаю, что пожалуй ты прав: SpinLock не стоило относить к высокоуровневым.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[4]: Memory barrier не могу понять что это
От: okman Беларусь https://searchinform.ru/
Дата: 06.04.23 11:21
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>В конечном машинном коде будет mfence или как вариант одна из sfence/lfence инструкций — они запрещают переупорядочивание доступа к памяти вокруг себя.


sfence/lfence/mfence — это малость для другого. В машинный код для x86/x64 практически всегда вставляется инструкция типа xchg, xadd или что-то подобное.
Re[5]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 06.04.23 12:35
Оценка:
Здравствуйте, okman, Вы писали:

O>sfence/lfence/mfence — это малость для другого. В машинный код для x86/x64 практически всегда вставляется инструкция типа xchg, xadd или что-то подобное.


Интересно, откуда инфа? Можно какие-нибудь доказательства, типа вот такой ссылки, ну или вот такой, или дизасм получающегося кода, или объяснение того, что именно будет делать функция типа

void Foo(){
Thread.MemoryBarrier();
}


Я ОООчень бы хотел узнать, почему вы так думаете, откуда вы это взяли и где тут логика.

ЗЫ: прежде чем отвечать сходите по приведённым ссылкам.

UPD: по своей же ссылке увидел

 #elif defined(HOST_X86)

  #define YieldProcessor() __asm { rep nop }
  #define MemoryBarrier() MemoryBarrierImpl()
  __forceinline void MemoryBarrierImpl()
  {
      int32_t Barrier;
      __asm {
          xchg Barrier, eax
      }
  }


Т.е. если платформа не AMD64 будет действительно xchg. Но логики я тут всё равно не вижу.
И да, где теперь найти X86 но не X86_64?
Всё сказанное выше — личное мнение, если не указано обратное.
Отредактировано 06.04.2023 13:00 Философ . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.