Re: поясните про volatile ?
От: breee breee  
Дата: 06.09.11 09:53
Оценка: 1 (1) +3
Здравствуйте, 23W, Вы писали:

23W>Уже несколько раз читал в разных местах, что volatile директива перед переменной не гарантирует атомарность операции с самой переменной, при работе с ней в несколько потоков. Так ли это ?

23W>Действительно, разве изменение volatile bool или volatile BYTE переменной может быть не атомарной ? ведь это примитивный байтовый тип изменяемый за одну asm операцию. Или все же нужно менять содержимое таких переменных через Intelock???

23W>Прошу помощи.


volatile к атомарности не имеет вообще никакого отношения.
Re[6]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 12:03
Оценка: -2 :)
Здравствуйте, rus blood, Вы писали:

RB>

RB>В VS2005 volatile дополнительно к подавлению оптимизации работает как барьер соответствующей операции для самого компилятора (но не для процессора).
RB>Никакой атомарности для произвольных типов он не обеспечивает.


Для начала нужно в терминах разобраться, барьер суть примитив синхронизации потоков который позволяет заблокировать потоки в одной точке до завершения условия (например завершения потоков), а упорядоченный доступ к памяти это запрет на перестановку инструкций компилятором в целях оптимизации.
Re[15]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 12:48
Оценка: -3
Здравствуйте, sysenter, Вы писали:

S>volatile нужен, чтобы компилятор не применял оптимизацию и только. Оптимизация подразумевает в том числе и перестановку ассемблерных инструкций.


+ проц не будет хранить значение volatile переменной в кеше, а только в памяти.
Re[16]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 12:50
Оценка: +3
Здравствуйте, sysenter, Вы писали:

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

S>>volatile нужен, чтобы компилятор не применял оптимизацию и только. Оптимизация подразумевает в том числе и перестановку ассемблерных инструкций.
S>+ проц не будет хранить значение volatile переменной в кеше, а только в памяти.
а вот это уже явно — неправда.
Re[9]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 11:05
Оценка: 12 (1) :)
Здравствуйте, sysenter, Вы писали:

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


RB>>В VS2005 volatile дополнительно к подавлению оптимизации работает как барьер соответствующей операции для самого компилятора (но не для процессора).

RB>>Никакой атомарности для произвольных типов он не обеспечивает.

S>Откуда информация?


От самого MS VC 2005

; 120  :         volatile __int64 x;
; 121  : 
; 122  :         x = 1;

  00037    c7 45 e0 01 00
    00 00         mov     DWORD PTR _x$155193[ebp], 1
  0003e    89 75 e4     mov     DWORD PTR _x$155193[ebp+4], esi
Имею скафандр — готов путешествовать!
Re[6]: поясните про volatile ?
От: Jolly Roger  
Дата: 06.09.11 10:23
Оценка: 2 (1) +1
Здравствуйте, rus blood, Вы писали:

RB>На интеловских процессорах load/store операции с данными, размером меньше разрядности (<= 4 для x86 и <= 8 для x64) атомарны.


Только если они выравнены на границу 4(8) байт.
"Нормальные герои всегда идут в обход!"
Re[15]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 12:51
Оценка: 1 (1) +1
Здравствуйте, sysenter, Вы писали:

S>Если не выровнены, будет дополнительная операция чтения перед которой может вклиниться другой поток + падение производительности на чтении не выровненных данных.


Пентиум читает/пишет целыми кеш-лайнами. Которые могут быть и 8 байт, и 16, и 32 и даже 64, в зависимости от модели процессора.

Как данные выровнены внутри кеш-лайна, процессору все равно. Если данные пересекают границу кеш-лайна, насколько я понимаю, аппаратура не гарантирует атомарного обращения, чего бы не было написано в программе.
Re[9]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 11:02
Оценка: -2
Здравствуйте, sysenter, Вы писали:

S>В других версиях VS атомарность volatile уже не обеспечивается?

да. представьте себе
из того что А тождественно Б, не означает что и Б тождественно А. (это так, пример из логики).
Re[2]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 11:10
Оценка: -2
Здравствуйте, Pzz, Вы писали:

Pzz>volatile означает лишь одно: говорит компилятору, что к переменной может быть доступ помимо его "глаз". Это приводит к тому, что компилятор не может кешировать значение переменной в регистре, а вынужден генерировать обращение к памяти при каждом обращении.


Если быть технически точным, то говорит процу сбрасывать кэш линейку, соответствующую адресу в памяти переменной и брать значение из памяти при чтении. Так же запись будет производиться сразу в память вместо записи в кеш. Так же будет блокироваться шина у соответсвующей микросхемы памяти на время чтения/записи в памяти.
Re[13]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 11:19
Оценка: :))
Здравствуйте, rus blood, Вы писали:

RB>2. Действительно, разве изменение volatile bool или volatile BYTE переменной может быть не атомарной ?

RB>Если под словом "изменение" понимается одиночная store-операция, то не может.

АлёнаЦПП пишет:

Казалось бы уж что-что, так bool должен писаться в один прием. Я вычитала, что на некоторых Windows'ах это вовсе даже и не так. И атомарность присутствует только при работе с char
Re[4]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 11:54
Оценка: -1 :)
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, 23W, Вы писали:


23W>>Здравствуйте, Pzz, Вы писали:

Pzz>>>Вывод: используйте InterlockedXXX() или механизмы синхронизации.

23W>>Спасибо.


RB>Знаешь, почему такой срач возник?

RB>Потому что ты не объяснил, какие именно операции ты выполняешь с переменными.

RB>Вот у тебя есть переменная, пусть даже volatile

RB>
volatile long flag;


RB>Типичные операции с переменной

RB>1. Запись значения
RB>
flag = 1;


RB>2. Чтение значения

RB>
long f = flag;


RB>3. Чтение/Изменение/Запись

RB>
flag ++;


RB>В первых двух случаях имеется простые read и write операции, они атомарны, и никакой синхронизации сами по себе не требуют.

RB>В последнем случае будет выполнены последовательно read и write операции, которые совместно — не атомарны.
RB>Ни смотря на слово volatile, и на "волшебные" возможности MSVC2005, как некоторые считают.

RB>Для атомарности операций в последнем случае и предусмотрены interlocked-операции.

RB>Все interlocked-операции производят read-modify-write последовательность действий (хотя в некоторых случаях шаг modify может отсутствовать).
RB>В этом их отличие от простых read или write и предназначение.


Если несколько цепочек одновременно пишут в flag, разве операция 2 тоже атомарна ? Вернее не так, разве операция 2 прочитает некое валидное значение записанное одной из цепочек (последней), не будет ли там "микс" из нескольких значений.
Далее, если операция один всегда атомарна, накой в API реализовали InterlockedExchange() ??

P.S.: касательно операции 3. — volatile не разрешает делать ++ с переменной.
Re[17]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 12:54
Оценка: -2
Здравствуйте, 23W, Вы писали:

.S>>+ проц не будет хранить значение volatile переменной в кеше, а только в памяти.

23W>а вот это уже явно — неправда.

Строго говоря, значение volatile переменной не будет храниться в регистре это факт.
Но, у ядер современных процов есть не разделяемые кеши и если хранить такую переменную в кеше, которая изменяется незаметно, то ядро просто этого не заметит. Логично предположить, что ядро каждый раз её из памяти читает.
Re[18]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 12:58
Оценка: +2
Здравствуйте, sysenter, Вы писали:

S>Строго говоря, значение volatile переменной не будет храниться в регистре это факт.

S>Но, у ядер современных процов есть не разделяемые кеши и если хранить такую переменную в кеше, которая изменяется незаметно, то ядро просто этого не заметит. Логично предположить, что ядро каждый раз её из памяти читает.

У тебя неверное представление об архитектуре интеловских процессоров.
Все, на самом деле, не так.
Имею скафандр — готов путешествовать!
Re[16]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:33
Оценка: +1 :)
Здравствуйте, Jolly Roger, Вы писали:

Pzz>>В общем, если не хотите приключений на собственную ж..., лучше предохраняться использовать предназначенные для этого атомарные операции и/или примитивы синхронизации.


JR>Так проще, но не всегда лучше.


Ну скажем так. Множества людей, способных руками сделать лучше и людей, задающих наивные вопросы, почти не пересекаются
Re[23]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 14:09
Оценка: 5 (1)
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, rus blood, Вы писали:


RB>>Это вовсе не тот случай.

RB>>Это случай последовательных store-load по разным адресам, который как раз и может быть re-ordered процессором.
RB>>И не надо было столько копий ломать, когда это явно сказано в мануале:
RB>>8.2.3.4 Loads May Be Reordered with Earlier Stores to Different Locations

JR>А это из какого мануала?


У меня это набор скачанных с сайта документов.
Intel постоянно меняют название самого документа, как и состав разного набора документов по этой теме.
Поискал, сейчас это называется так.

Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 3A (PDF)

В частности, часть 8.2 — memory ordering.
Имею скафандр — готов путешествовать!
Re[3]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 11:45
Оценка: 4 (1)
Здравствуйте, 23W, Вы писали:

23W>Здравствуйте, Pzz, Вы писали:

Pzz>>Вывод: используйте InterlockedXXX() или механизмы синхронизации.

23W>Спасибо.


Знаешь, почему такой срач возник?
Потому что ты не объяснил, какие именно операции ты выполняешь с переменными.

Вот у тебя есть переменная, пусть даже volatile
volatile long flag;


Типичные операции с переменной
1. Запись значения
flag = 1;


2. Чтение значения
long f = flag;


3. Чтение/Изменение/Запись
flag ++;


В первых двух случаях имеется простые read и write операции, они атомарны, и никакой синхронизации сами по себе не требуют.
В последнем случае будет выполнены последовательно read и write операции, которые совместно — не атомарны.
Ни смотря на слово volatile, и на "волшебные" возможности MSVC2005, как некоторые считают.

Для атомарности операций в последнем случае и предусмотрены interlocked-операции.
Все interlocked-операции производят read-modify-write последовательность действий (хотя в некоторых случаях шаг modify может отсутствовать).
В этом их отличие от простых read или write и предназначение.
Имею скафандр — готов путешествовать!
Re[12]: поясните про volatile ?
От: Jolly Roger  
Дата: 06.09.11 12:01
Оценка: 4 (1)
Здравствуйте, 23W, Вы писали:

23W>Здравствуйте, rus blood, Вы писали:


RB>>Здравствуйте, 23W, Вы писали:


RB>>>>Interlocked-операция на невыровненных данных может вообще не работать так, как ты от нее ожидаешь.

23W>>>ну вы меня вообще в тупик поставили, а как же тонны кода которые используют InterlockedIncrement() и подобное?

RB>>Они работают на выровненных данных.

23W>спасибо, но как я понял из ваших же фраз на выровненных данных они и не нужны как бы, там атомарность гарантируется архитектурой.
23W>Каков ваш конечный совет ? только конкретно пожалуйста.

Например, если InterlockedIncrement заменить на A++, то мы получим следующие действия процессора:

1) Загрузить А из памяти в регистр процессора.
2) Увеличить содержимое регистра на единицу.
3) Выгрузить новое значение из регистра в память.

Допустим, наша А выровнена на границу 4-х байт, и платформа обеспечивает атомарность операций с ней. Тогда каждая из 3-х операций будет атомарной, но вся последовательность таковой не будет, и другой поток может записать в А новое значение сразу после того, как наш поток выполнил пункт 1). Вот для таких случаев и нужны InterlockedIncrement() и т.п. функции. Другая альтернатива — синхронизацию доступа, но Interlocked-функции более предпочтительны с точки зрения производительности.

Зачем нужна volatile? Такой пример:
Допустим, у нас есть два потока, один из которых должен выполнять некоторую фоновую задачу, дожидаясь, пока другой поток завершит некую длительную операцию. Тогда мы можем использовать флаг, состояние которого будет периодически опрашивать первый поток, а второй поток его взведёт после завершения своей операции. Для такого флага и требуется использовать volatile. Разумеется, здесь тоже можно использовать InterlockedIncrement, но это излишество, так как Interlocked-операции на той-же x86 заметно более затратны, чем просто запись в память.
"Нормальные герои всегда идут в обход!"
Re[18]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:13
Оценка: 4 (1)
Здравствуйте, sysenter, Вы писали:

S>Строго говоря, значение volatile переменной не будет храниться в регистре это факт.

S>Но, у ядер современных процов есть не разделяемые кеши и если хранить такую переменную в кеше, которая изменяется незаметно, то ядро просто этого не заметит. Логично предположить, что ядро каждый раз её из памяти читает.

Пентиум умеет синхронизировать кеши между процессорами/ядрами так, что программисту это незаметно. Это называется "когерентный кэш". И да, они между собой переговариваются, чтобы знать, когда синхронизировать кэш
Re[16]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:11
Оценка: 2 (1)
Здравствуйте, 23W, Вы писали:

Pzz>>В общем, если не хотите приключений на собственную ж..., лучше предохраняться использовать предназначенные для этого атомарные операции и/или примитивы синхронизации.

23W>Скажите, как такое поведение процессора может сказаться на атомарности операции записи или чтения выровренных данных. Ведь два процессора одновременно писать в одну ячейку памяти не могут, только последовательно (шина то — одна).

В одном потоке вы пишете: flag = true; i = 5. Другой поток, на другом процессоре, может увидеть на мгновение, что i уже 5, а flag все еще false. Атомарности операций это не противоречит, но вот порядок исполнения — другой. А если то же самое делать через InterlockedXXX(), или под мьютексом, то порядок будет правильный, такой же, как в тексте.
Re: поясните про volatile ?
От: MasterZiv СССР  
Дата: 06.09.11 09:54
Оценка: 1 (1)
On 06.09.2011 13:46, 23W wrote:
> Уже несколько раз читал в разных местах, что volatile директива перед переменной
> не гарантирует атомарность операции с самой переменной, при работе с ней в
> несколько потоков. Так ли это ?

Так. volatile может быть объявлена любая переменная, любого типа.

Вообще, volatile -- это инструкция компилятору, чтобы он не делал
никаких предположений о текущем значении переменной для целей оптимизации.
Более ничего.

> Действительно, разве изменение volatile bool или volatile BYTE переменной может

> быть не атомарной ?

Может.

ведь это примитивный байтовый тип изменяемый за одну asm
> операцию.

Кто тебе это сказал ? Ссылку на стандарт даш ?

Или все же нужно менять содержимое таких переменных через Intelock???

Нужно. В смысле, нужно синхронизироваться, что такое Intelock я слабо представляю.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 10:48
Оценка: :)
Здравствуйте, sysenter, Вы писали:

S>У VS есть нестандартное расширение трактовки volatile, это расширение гарантирует атомарность операции. В MSDN об этом написано.


Об этом же пишет многоуважаемая АленаЦэКрестКрест.
Re[8]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 10:51
Оценка: +1
Здравствуйте, 23W, Вы писали:

23W>Т.е. я правильно понимаю что для данных размеров в байт (и это только тип char) можно не заморачиваться и считать что изменения volatile char будут атомарны. А вот при работе с двух-байтовыми данными (и более) нужна именно interlocked-операция, т.к. из-за невыровненности они могут быть неатомарны.


Interlocked-операция на невыровненных данных может вообще не работать так, как ты от нее ожидаешь.
Имею скафандр — готов путешествовать!
Re[7]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 10:55
Оценка: +1
Здравствуйте, sysenter, Вы писали:

S>АленаCPP утверждает, что в доке к VS 2005 написано про атомарность volatile.


Плевать на Алену.

В VS2005 volatile дополнительно к подавлению оптимизации работает как барьер соответствующей операции для самого компилятора (но не для процессора).
Никакой атомарности для произвольных типов он не обеспечивает.
Имею скафандр — готов путешествовать!
Re[8]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 10:55
Оценка: -1
Здравствуйте, sysenter, Вы писали:

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


23W>>"Я нашла этот пункт только в документации к Visual Studio 2005. Я порылась на MSDN в поисках этого пункта в других версиях Visual Studio, не нашла."


S>Update 3.11.2006

S>volatile в исполнении Микрософт имеет Microsoft Specific пункт. А именно: атомарность операций гарантируется и, как следствие, использование в многопоточных программах приветствуется. Но код получается непортируемым, соответственно.
S>Я нашла этот пункт только в документации к Visual Studio 2005


S>Ровно про это я и говорил.

а если глянуть двумя строками ниже, увидите то что я написал. Т.е. атомартность для volatile в VC++ гарантировалась на этапе Visual Studio 2005, потом эту строку из MSDN убрали!
Re[9]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 10:57
Оценка: :)
Здравствуйте, 23W, Вы писали:

23W>а если глянуть двумя строками ниже, увидите то что я написал. Т.е. атомартность для volatile в VC++ гарантировалась на этапе Visual Studio 2005, потом эту строку из MSDN убрали!


Что не означает, что компилятор перестал гарантировать атомарность volatile или у вас есть другие сведения?
Re[14]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 11:37
Оценка: +1
Здравствуйте, sysenter, Вы писали:

S>АлёнаЦПП пишет:


S>Казалось бы уж что-что, так bool должен писаться в один прием. Я вычитала, что на некоторых Windows'ах это вовсе даже и не так. И атомарность присутствует только при работе с char


А при чем тут Windows ?

ЗЫ
Вы сейчас очень сильно роняете авторитет Алены в моих глазах
Имею скафандр — готов путешествовать!
Re[4]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 11:49
Оценка: :)
Здравствуйте, rus blood, Вы писали:

RB>3. Чтение/Изменение/Запись

RB>
flag ++;


Может так?

++flag ;
Re[7]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 12:03
Оценка: +1
Здравствуйте, sysenter, Вы писали:

S>Ты изменяешь временный объект, который обратно в переменную не записывается


Садись, два.
Имею скафандр — готов путешествовать!
Re[14]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 12:51
Оценка: +1
Здравствуйте, 23W, Вы писали:

23W>1. простая операция чтения из переменной (1, 2, 4 байта) — атомарна.

да
23W>2. простая операция записи в такую же переменную — атомарна.
да
23W>3. сложные операторы и комбинации операций 1. и 2. — не атомарны и требуют вызова InterlockedXXX.
в многопоточных приложениях — да
23W>Причем операции 1 и 2 атомарны для 2 и 4 байтовых переменных если они выровнены (кстатий, вопрос — а если нет, что тогда?). Для однобайтных переменных операции 1 и 2 всегда атомарны.
да
23W>Атомарность операций 1 и 2 гарантируется архитектурой, а чтобы эта гарантия не была испорчена оптимизирующим компиляторам — нужна директива volatile переде переменными (и только для этого).

атомарность гарантируется архитектурой процессора, и компилятор и слово volatile здесь не причем.

Volatile только подавляет оптимизацию работы с переменной в компиляторе. Т.е., везде, где у тебя выполняются какие-то действия с такой переменной, компилятор будет честно вставлять операции чтения/записи в оперативную память, даже если у него под рукой будет регистр с значением этой переменной. У MSVC есть дополнительная плюшка — действие с volatile переменной (чтение или запись) является барьером для других операций такого же типа (чтение или запись). Т.е., компилятор не поменяет их местами.

23W>P.S.: как я уже спросил, — что делать если пемеренные 2 и 4х байтные и при этом не выровнены по адресу памяти (т.е. разделены границей кеш-линии).



Я не знаю.
Обычно переменные выровнены так, как надо.
Чтобы получить невыровеннные данные надо специально "целится себе в ногу".
Имею скафандр — готов путешествовать!
Re[16]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 12:52
Оценка: +1
Здравствуйте, sysenter, Вы писали:

S>>volatile нужен, чтобы компилятор не применял оптимизацию и только. Оптимизация подразумевает в том числе и перестановку ассемблерных инструкций.


S>+ проц не будет хранить значение volatile переменной в кеше, а только в памяти.


Не проц, а компилятор, и не в кеше, а в регистре.
Re[14]: поясните про volatile ?
От: Jolly Roger  
Дата: 06.09.11 13:11
Оценка: +1
Здравствуйте, 23W, Вы писали:

23W>Суммируя то что сказали Jolly Roger и rus blood.

23W>Я понял что:
23W>1. простая операция чтения из переменной (1, 2, 4 байта) — атомарна.
23W>2. простая операция записи в такую же переменную — атомарна.
23W>3. сложные операторы и комбинации операций 1. и 2. — не атомарны и требуют вызова InterlockedXXX.

В общем и целом — да.

23W>Причем операции 1 и 2 атомарны для 2 и 4 байтовых переменных если они выровнены (кстатий, вопрос — а если нет, что тогда?).


Тогда для её записи или чтения процессору может потребоваться два обращения к шине.

23W>Атомарность операций 1 и 2 гарантируется архитектурой, а чтобы эта гарантия не была испорчена оптимизирующим компиляторам — нужна директива volatile переде переменными (и только для этого).

23W>Правильно ?

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

23W>P.S.: как я уже спросил, — что делать если пемеренные 2 и 4х байтные и при этом не выровнены по адресу памяти (т.е. разделены границей кеш-линии).


Кэш управляется процессором, он "прозрачен" для программы, поэтому в данном случае лучше вообще не брать во внимание наличие кэшей.

PS Вообще на RSDN на эту тему было очень много обсуждений , лучше воспользуйтесь поиском и внимательно прочитайте, это будет полезно.
"Нормальные герои всегда идут в обход!"
Re[18]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:38
Оценка: +1
Здравствуйте, 23W, Вы писали:

23W>Например такая переменная volatile LONG служит событием, где какой-либо поток проверяет ее на >0 чтобы начать обрабатывать данные, а другой поток взводит ее в 1 когда подготовил данные для первого потока. Изначально же эта переменная была 0.


Может получиться так, что глазами того потока, который проверяет, переменная уже >0, а данные еще "не приехали". А вот если бы "другой поток" сделал бы InterlockedIncrement(), так бы не получилось.

Сама по себе атомарность мало кому нужна. Нужен консистентный доступ к объемам памяти, несколько превышающим 4 байта
Re[20]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:45
Оценка: +1
Здравствуйте, sysenter, Вы писали:

S>Про то, что ядра синхронизируют кеши я вкурсе. Как быть с DMA если он незаметно в оперативке поменяет значение volatile переменной или если эта переменная есть на самом деле участок памяти отображённый на устройство? Как проц узнает, что значение в памяти поменялось, если оно меняется при каждом считывании?


DMA не проходит мимо чипсета. Чипсет умеет общаться с процессором.

Если устройство отображается на память, есть 2 варианта: либо пометить соответствующие страницы, как некешируемые, либо програмно сбрасывать кеш до/после изменения данных, в зависимости от направления передачи.
поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 09:46
Оценка:
Уже несколько раз читал в разных местах, что volatile директива перед переменной не гарантирует атомарность операции с самой переменной, при работе с ней в несколько потоков. Так ли это ?
Действительно, разве изменение volatile bool или volatile BYTE переменной может быть не атомарной ? ведь это примитивный байтовый тип изменяемый за одну asm операцию. Или все же нужно менять содержимое таких переменных через Intelock???

Прошу помощи.
Re: поясните про volatile ?
От: se_sss  
Дата: 06.09.11 09:54
Оценка:
Для начала — компилятор имеет право вообще игнорировать модификатор.
А если не игнорирует, то должен отключать оптимизации при работе с этой переменной.
Что конкретно он должен делать и чего не должен — как я понимаю, не специфицировано.
Re[2]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 09:55
Оценка:
Здравствуйте, breee breee, Вы писали:

BB>Здравствуйте, 23W, Вы писали:


23W>>Уже несколько раз читал в разных местах, что volatile директива перед переменной не гарантирует атомарность операции с самой переменной, при работе с ней в несколько потоков. Так ли это ?

23W>>Действительно, разве изменение volatile bool или volatile BYTE переменной может быть не атомарной ? ведь это примитивный байтовый тип изменяемый за одну asm операцию. Или все же нужно менять содержимое таких переменных через Intelock???

23W>>Прошу помощи.


BB>volatile к атомарности не имеет вообще никакого отношения.


т.е. изменение volatile bool переменной из нескольких цепочек ТРЕБУЕТ защиты ее через объекты синхронизации?
Re[3]: поясните про volatile ?
От: breee breee  
Дата: 06.09.11 09:57
Оценка:
Здравствуйте, 23W, Вы писали:

23W>т.е. изменение volatile bool переменной из нескольких цепочек ТРЕБУЕТ защиты ее через объекты синхронизации?


Да.
Re[4]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 10:03
Оценка:
Здравствуйте, breee breee, Вы писали:

BB>Здравствуйте, 23W, Вы писали:

23W>>т.е. изменение volatile bool переменной из нескольких цепочек ТРЕБУЕТ защиты ее через объекты синхронизации?
BB>Да.

У меня тут есть определенный скепсис, как может изменение volatile bool или volatile BYTE быть не атомарным? Вы могли бы доказать или дать ссылку на стандарт или авторитет по этой теме.
Я понимаю что volatile отключает оптимизацию, т.е. гарантируется постоянная проверка переменной. Но ведь операция с байтом должна быть примитивной (атомарной).
Re: поясните про volatile ?
От: max-maxtor Россия www.rsdn.ru
Дата: 06.09.11 10:07
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Уже несколько раз читал в разных местах, что volatile директива перед переменной не гарантирует атомарность операции с самой переменной, при работе с ней в несколько потоков. Так ли это ?

23W>Действительно, разве изменение volatile bool или volatile BYTE переменной может быть не атомарной ? ведь это примитивный байтовый тип изменяемый за одну asm операцию. Или все же нужно менять содержимое таких переменных через Intelock???

23W>Прошу помощи.


Почему она должна горантировать в С++ атомарность.
Не длжна просто оператор для того что бы эту переменную компелятор не поаптимизировал на случай если ты собираешься неведомымспособом для компилятора С++ модифицировать значение этой переменной.
Re[5]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 10:13
Оценка:
Здравствуйте, 23W, Вы писали:

23W>У меня тут есть определенный скепсис, как может изменение volatile bool или volatile BYTE быть не атомарным? Вы могли бы доказать или дать ссылку на стандарт или авторитет по этой теме.

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

На интеловских процессорах load/store операции с данными, размером меньше разрядности (<= 4 для x86 и <= 8 для x64) атомарны.
Имею скафандр — готов путешествовать!
Re[5]: поясните про volatile ?
От: mike_rs Россия  
Дата: 06.09.11 10:18
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Здравствуйте, breee breee, Вы писали:


BB>>Здравствуйте, 23W, Вы писали:

23W>>>т.е. изменение volatile bool переменной из нескольких цепочек ТРЕБУЕТ защиты ее через объекты синхронизации?
BB>>Да.

23W>У меня тут есть определенный скепсис, как может изменение volatile bool или volatile BYTE быть не атомарным? Вы могли бы доказать или дать ссылку на стандарт или авторитет по этой теме.


изменение будет атомарным в пределах одного ядра. В случае нескольких ядер обязательно нужно использовать memory barrier, которые достигаются с помощью interlocked операций.
Re[6]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 10:27
Оценка:
Здравствуйте, mike_rs, Вы писали:

_>изменение будет атомарным в пределах одного ядра. В случае нескольких ядер обязательно нужно использовать memory barrier, которые достигаются с помощью interlocked операций.


В случае нескольких ядер отдельная load или store операция с данными размером в байт также будет атомарна.
Данные большего размера (2, 4, 8 на x64) байт обычно выровнены, поэтому операции с ними также будут атомарны.

Барьеры используются для обеспечения правильного порядка выполнения и видимости на других ядрах последовательных операций load/store.
Т.е., когда последовательно идут load-load, load-store, store-store или store-load операции.
Если у вас выполняется один load (или один store) из переменной volatile, где вы тут собираетесь барьеры вставлять?

Барьеры реализуются не только с помощью interlocked-операций, есть специальные команды процессора.
То, что interlocked-операция работает в качестве барьера, может зависеть от реализации процессора ("расслабленности").
Имею скафандр — готов путешествовать!
Re[5]: поясните про volatile ?
От: breee breee  
Дата: 06.09.11 10:28
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Здравствуйте, breee breee, Вы писали:


BB>>Здравствуйте, 23W, Вы писали:

23W>>>т.е. изменение volatile bool переменной из нескольких цепочек ТРЕБУЕТ защиты ее через объекты синхронизации?
BB>>Да.

23W>У меня тут есть определенный скепсис, как может изменение volatile bool или volatile BYTE быть не атомарным? Вы могли бы доказать или дать ссылку на стандарт или авторитет по этой теме.

Вам известны все существующие и будущие архитектуры процессоров, чтобы быть в этом увереным? Ссылку на стандарт дать невозможно, т.к. в текущем стандарте (2003 года) нет ничего про многопоточность, атомарность и т.д., поэтому мы должны предполагать худший случай.

23W>Я понимаю что volatile отключает оптимизацию, т.е. гарантируется постоянная проверка переменной.

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

23W>Но ведь операция с байтом должна быть примитивной (атомарной).

Откуда эта информация?
Re[6]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 10:33
Оценка:
Здравствуйте, breee breee, Вы писали:

BB>Здравствуйте, 23W, Вы писали:


23W>>Но ведь операция с байтом должна быть примитивной (атомарной).

BB>Откуда эта информация?
rus blood подтвердил (для x86 и x64 платформ).
Re[7]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 10:36
Оценка:
Здравствуйте, rus blood, Вы писали:

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


_>>изменение будет атомарным в пределах одного ядра. В случае нескольких ядер обязательно нужно использовать memory barrier, которые достигаются с помощью interlocked операций.


RB>В случае нескольких ядер отдельная load или store операция с данными размером в байт также будет атомарна.

RB>Данные большего размера (2, 4, 8 на x64) байт обычно выровнены, поэтому операции с ними также будут атомарны.

RB>Барьеры используются для обеспечения правильного порядка выполнения и видимости на других ядрах последовательных операций load/store.

RB>Т.е., когда последовательно идут load-load, load-store, store-store или store-load операции.
RB>Если у вас выполняется один load (или один store) из переменной volatile, где вы тут собираетесь барьеры вставлять?

RB>Барьеры реализуются не только с помощью interlocked-операций, есть специальные команды процессора.

RB>То, что interlocked-операция работает в качестве барьера, может зависеть от реализации процессора ("расслабленности").

Т.е. я правильно понимаю что для данных размеров в байт (и это только тип char) можно не заморачиваться и считать что изменения volatile char будут атомарны. А вот при работе с двух-байтовыми данными (и более) нужна именно interlocked-операция, т.к. из-за невыровненности они могут быть неатомарны.
Re[4]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 10:42
Оценка:
Здравствуйте, breee breee, Вы писали:

23W>>т.е. изменение volatile bool переменной из нескольких цепочек ТРЕБУЕТ защиты ее через объекты синхронизации?

BB>Да.

У VS есть нестандартное расширение трактовки volatile, это расширение гарантирует атомарность операции. В MSDN об этом написано.
Re[5]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 10:47
Оценка:
Здравствуйте, sysenter, Вы писали:

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


23W>>>т.е. изменение volatile bool переменной из нескольких цепочек ТРЕБУЕТ защиты ее через объекты синхронизации?

BB>>Да.

S>У VS есть нестандартное расширение трактовки volatile, это расширение гарантирует атомарность операции. В MSDN об этом написано.

Вот это место из MSDN (http://msdn.microsoft.com/ru-ru/library/12a04hfd.aspx)
Objects declared as volatile are not used in certain optimizations because their values can change at any time. The system always reads the current value of a volatile object at the point it is requested, even if a previous instruction asked for a value from the same object. Also, the value of the object is written immediately on assignment. 

Also, when optimizing, the compiler must maintain ordering among references to volatile objects as well as references to other global objects. In particular, 

A write to a volatile object (volatile write) has Release semantics; a reference to a global or static object that occurs before a write to a volatile object in the instruction sequence will occur before that volatile write in the compiled binary.

A read of a volatile object (volatile read) has Acquire semantics; a reference to a global or static object that occurs after a read of volatile memory in the instruction sequence will occur after that volatile read in the compiled binary.

This allows volatile objects to be used for memory locks and releases in multithreaded applications.

и где тут про атомарность ?
Re[7]: поясните про volatile ?
От: breee breee  
Дата: 06.09.11 10:49
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Здравствуйте, breee breee, Вы писали:


BB>>Здравствуйте, 23W, Вы писали:


23W>>>Но ведь операция с байтом должна быть примитивной (атомарной).

BB>>Откуда эта информация?
23W>rus blood подтвердил (для x86 и x64 платформ).

Это подфорум о чистом C++. Если конкретная платформа и компилятор обеспечивают атомарность, это еще не значит, что на это можно полагаться в общем случае.
Кроме того для x86 и x64, синхронизация все еще требуется для обеспечения видимости, насколько я понимаю.
Re[6]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 10:50
Оценка:
Здравствуйте, 23W, Вы писали:

23W>и где тут про атомарность ?


АленаCPP утверждает, что в доке к VS 2005 написано про атомарность volatile.
Re[6]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 10:51
Оценка:
Здравствуйте, sysenter, Вы писали:

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


S>>У VS есть нестандартное расширение трактовки volatile, это расширение гарантирует атомарность операции. В MSDN об этом написано.


S>Об этом же пишет многоуважаемая АленаЦэКрестКрест.

Вот ее фраза если точно:

"Я нашла этот пункт только в документации к Visual Studio 2005. Я порылась на MSDN в поисках этого пункта в других версиях Visual Studio, не нашла."
Re[7]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 10:53
Оценка:
Здравствуйте, 23W, Вы писали:

23W>"Я нашла этот пункт только в документации к Visual Studio 2005. Я порылась на MSDN в поисках этого пункта в других версиях Visual Studio, не нашла."


Update 3.11.2006
volatile в исполнении Микрософт имеет Microsoft Specific пункт. А именно: атомарность операций гарантируется и, как следствие, использование в многопоточных программах приветствуется. Но код получается непортируемым, соответственно.
Я нашла этот пункт только в документации к Visual Studio 2005


Ровно про это я и говорил.
Re[9]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 10:53
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, 23W, Вы писали:


23W>>Т.е. я правильно понимаю что для данных размеров в байт (и это только тип char) можно не заморачиваться и считать что изменения volatile char будут атомарны. А вот при работе с двух-байтовыми данными (и более) нужна именно interlocked-операция, т.к. из-за невыровненности они могут быть неатомарны.


RB>Interlocked-операция на невыровненных данных может вообще не работать так, как ты от нее ожидаешь.

ну вы меня вообще в тупик поставили, а как же тонны кода которые используют InterlockedIncrement() и подобное?
Re[10]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 10:58
Оценка:
Здравствуйте, 23W, Вы писали:

RB>>Interlocked-операция на невыровненных данных может вообще не работать так, как ты от нее ожидаешь.

23W>ну вы меня вообще в тупик поставили, а как же тонны кода которые используют InterlockedIncrement() и подобное?

Они работают на выровненных данных.
Имею скафандр — готов путешествовать!
Re[11]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 11:00
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, 23W, Вы писали:


RB>>>Interlocked-операция на невыровненных данных может вообще не работать так, как ты от нее ожидаешь.

23W>>ну вы меня вообще в тупик поставили, а как же тонны кода которые используют InterlockedIncrement() и подобное?

RB>Они работают на выровненных данных.

спасибо, но как я понял из ваших же фраз на выровненных данных они и не нужны как бы, там атомарность гарантируется архитектурой.
Каков ваш конечный совет ? только конкретно пожалуйста.
Re[8]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 11:00
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>В VS2005 volatile дополнительно к подавлению оптимизации работает как барьер соответствующей операции для самого компилятора (но не для процессора).

RB>Никакой атомарности для произвольных типов он не обеспечивает.

Откуда информация? В других версиях VS атомарность volatile уже не обеспечивается?
Re[10]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 11:02
Оценка:
Здравствуйте, sysenter, Вы писали:

S>Что не означает, что компилятор перестал гарантировать атомарность volatile или у вас есть другие сведения?


При компиляции под x86 (win32) следующий код
volatile __int64 x;
.............
x = 0i64;

выльется в две store-операции.

И никакой атомарности.
Имею скафандр — готов путешествовать!
Re: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 11:04
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Действительно, разве изменение volatile bool или volatile BYTE переменной может быть не атомарной ? ведь это примитивный байтовый тип изменяемый за одну asm операцию. Или все же нужно менять содержимое таких переменных через Intelock???


1. То, что в Си выглядит одной строкой, в ассемблере может быть несколькими командами. Которые, естественно, не атомарны
2. Процессор может обращаться к памяти не в том порядке, в котором обращения к памяти записаны в программе. Глядя из другого потока, это может быть заметно.

volatile означает лишь одно: говорит компилятору, что к переменной может быть доступ помимо его "глаз". Это приводит к тому, что компилятор не может кешировать значение переменной в регистре, а вынужден генерировать обращение к памяти при каждом обращении.

Вывод: используйте InterlockedXXX() или механизмы синхронизации.
Re[2]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 11:06
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>Вывод: используйте InterlockedXXX() или механизмы синхронизации.

Спасибо.
Re[12]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 11:12
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Каков ваш конечный совет ? только конкретно пожалуйста.


Совет в чем?

Вот ваши вопросы

1. Уже несколько раз читал в разных местах, что volatile директива перед переменной не гарантирует атомарность операции с самой переменной, при работе с ней в несколько потоков. Так ли это ?
В общем случае, да, так.
Например, на x86 любые load/store операции с переменной типа __int64 будут неатомарны.

2. Действительно, разве изменение volatile bool или volatile BYTE переменной может быть не атомарной ?
Если под словом "изменение" понимается одиночная store-операция, то не может.

3. Или все же нужно менять содержимое таких переменных через Intelock???
Необязательно.
Имею скафандр — готов путешествовать!
Re[3]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 11:12
Оценка:
Здравствуйте, sysenter, Вы писали:

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


Это interlocked так делает, а volatile — нет. В этом между ними разница.
Re[4]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 11:15
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Это interlocked так делает, а volatile — нет. В этом между ними разница.


Да, верно, параллельно книгу читаю, ваш ответ не полностью прочитал.
Re[4]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 11:53
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>В последнем случае будет выполнены последовательно read и write операции, которые совместно — не атомарны.

RB>Ни смотря на слово volatile, и на "волшебные" возможности MSVC2005, как некоторые считают.

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

volatile makes the memory accesses ordered.

Отсюда.
Re[5]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 11:54
Оценка:
Здравствуйте, sysenter, Вы писали:

S>Может так?


Какое это имеет отношение к теме атомарности?
Вообще, какая разница между
flag++;

и
++flag;

?
Имею скафандр — готов путешествовать!
Re[5]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 11:57
Оценка:
Здравствуйте, sysenter, Вы писали:

S>Некоторые обоснованно считают, что компилятор может переставить местами инструкции, а при volatile компилятор (VS 2005) придерживается

S>исходного порядка.

S>volatile makes the memory accesses ordered.


И что??

В VS2005 volatile дополнительно к подавлению оптимизации работает как барьер соответствующей операции для самого компилятора (но не для процессора).
Никакой атомарности для произвольных типов он не обеспечивает.

Имею скафандр — готов путешествовать!
Re[6]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 11:58
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Какое это имеет отношение к теме атомарности?

RB>Вообще, какая разница между
RB>
flag++;

RB>и
RB>
++flag;

RB>?

Ты изменяешь временный объект, который обратно в переменную не записывается т.е. вместо read/increment/write у тебя read/increment.
Чтение может произойти в регистр там же инкрементировано и записано в новую ячейку памяти или не записано вообще на усмотрение компилятора т.к. операция инкремента временного объекта который ничему не присваивается может быть отброшена компилятором.
Re[5]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 12:01
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Если несколько цепочек одновременно пишут в flag, разве операция 2 тоже атомарна ? Вернее не так, разве операция 2 прочитает некое валидное значение записанное одной из цепочек (последней), не будет ли там "микс" из нескольких значений.


Микса не будет.

И это и есть гарантия атомарности чтения данных.
На x86 это гарантия дается для 1,2,4-байтных выровненных данных.


23W>Далее, если операция один всегда атомарна, накой в API реализовали InterlockedExchange() ??

InterlockedExchange выполняет последовательность read-write.
Ведь одна возвращает исходное значение переменной, которое было на момент записи.
Простая последовательность
long oldValue = flag;
flag = newValue;
return oldValue;

атомарности не обеспечивает.

23W>P.S.: касательно операции 3. — volatile не разрешает делать ++ с переменной.

Чего?
Имею скафандр — готов путешествовать!
Re[8]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 12:04
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Садись, два.


Ты прав, что-то я подтормаживаю сегодня)
Re[7]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 12:07
Оценка:
Здравствуйте, sysenter, Вы писали:

S>Для начала нужно в терминах разобраться, барьер суть примитив синхронизации потоков который позволяет заблокировать потоки в одной точке до завершения условия (например завершения потоков), а упорядоченный доступ к памяти это запрет на перестановку инструкций компилятором в целях оптимизации.


Под барьером я имел в виду именно "барьер обращения к памяти".
Т.е., в твоих терминах — "запрет на перестановку инструкций".
И барьеры бывают как для компилятора, так и для процессора.

Вот для компилятора MSVC2005 слово volatile является барьером соответствующего типа.
В этом и есть специфика MSVC.

Но к атомарности это не имеет отношения.
Имею скафандр — готов путешествовать!
Re[5]: поясните про volatile ?
От: BSDыщъх  
Дата: 06.09.11 12:34
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Здравствуйте, breee breee, Вы писали:


BB>>Здравствуйте, 23W, Вы писали:

23W>>>т.е. изменение volatile bool переменной из нескольких цепочек ТРЕБУЕТ защиты ее через объекты синхронизации?
BB>>Да.

23W>У меня тут есть определенный скепсис, как может изменение volatile bool или volatile BYTE быть не атомарным? Вы могли бы доказать или дать ссылку на стандарт или авторитет по этой теме.

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

Например, операция инкремента, выполняющаяся из двух разных потоков.

1) загрузка в регистр.
2) модификация.
3) сохранение.

В двух параллельных потоках загрузка может выполниться параллельно.
В результате, значение увеличится на 1 а не на 2.

volatile сам по себе не гарантирует, что инкремент пройдёт одним махом и с блокировкой ячейки.

volatile нужен совсем для другого.

например
while (global_flag){ ... }

не будет оптимизирован в вечный цикл, если global_flag объявлен с модификатором volatile,
даже если global_flag не используется внутри цикла.
Sine vilitate, sine malitiosa mente
Re[13]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 12:38
Оценка:
Суммируя то что сказали Jolly Roger и rus blood.
Я понял что:
1. простая операция чтения из переменной (1, 2, 4 байта) — атомарна.
2. простая операция записи в такую же переменную — атомарна.
3. сложные операторы и комбинации операций 1. и 2. — не атомарны и требуют вызова InterlockedXXX.
Причем операции 1 и 2 атомарны для 2 и 4 байтовых переменных если они выровнены (кстатий, вопрос — а если нет, что тогда?). Для однобайтных переменных операции 1 и 2 всегда атомарны.
Атомарность операций 1 и 2 гарантируется архитектурой, а чтобы эта гарантия не была испорчена оптимизирующим компиляторам — нужна директива volatile переде переменными (и только для этого).
Правильно ?

P.S.: как я уже спросил, — что делать если пемеренные 2 и 4х байтные и при этом не выровнены по адресу памяти (т.е. разделены границей кеш-линии).


P.P.S: rus blood, я извиняюсь за оператор ++ и volatile — был неправ!
Re[14]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 12:44
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Атомарность операций 1 и 2 гарантируется архитектурой, а чтобы эта гарантия не была испорчена оптимизирующим компиляторам — нужна директива volatile переде переменными (и только для этого).

23W>Правильно ?

Отцы, вы забываете про то, что процессор может изменить порядок фактического обращения к памяти — по сравнению с ассемблерным кодом, а даже не сишным. При этом если "смотреть" с одного ядра, то для x86-х процессоров гарантируется, что вы этого не заметите. А вот если смотреть на ту же память с соседнего ядра, то можете и заметить.

В общем, если не хотите приключений на собственную ж..., лучше предохраняться использовать предназначенные для этого атомарные операции и/или примитивы синхронизации.
Re[14]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 12:44
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Причем операции 1 и 2 атомарны для 2 и 4 байтовых переменных если они выровнены (кстатий, вопрос — а если нет, что тогда?). Для однобайтных переменных операции 1 и 2 всегда атомарны.


Если не выровнены, будет дополнительная операция чтения перед которой может вклиниться другой поток + падение производительности на чтении не выровненных данных.

23W>Атомарность операций 1 и 2 гарантируется архитектурой, а чтобы эта гарантия не была испорчена оптимизирующим компиляторам — нужна директива volatile переде переменными (и только для этого).

23W>Правильно ?

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

23W>P.S.: как я уже спросил, — что делать если пемеренные 2 и 4х байтные и при этом не выровнены по адресу памяти (т.е. разделены границей кеш-линии).


Компилятор сам обычно выравнивает, но это можно отключить.
Re[15]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 12:53
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, 23W, Вы писали:


23W>>Атомарность операций 1 и 2 гарантируется архитектурой, а чтобы эта гарантия не была испорчена оптимизирующим компиляторам — нужна директива volatile переде переменными (и только для этого).

23W>>Правильно ?

Pzz>Отцы, вы забываете про то, что процессор может изменить порядок фактического обращения к памяти — по сравнению с ассемблерным кодом, а даже не сишным. При этом если "смотреть" с одного ядра, то для x86-х процессоров гарантируется, что вы этого не заметите. А вот если смотреть на ту же память с соседнего ядра, то можете и заметить.


Pzz>В общем, если не хотите приключений на собственную ж..., лучше предохраняться использовать предназначенные для этого атомарные операции и/или примитивы синхронизации.

Скажите, как такое поведение процессора может сказаться на атомарности операции записи или чтения выровренных данных. Ведь два процессора одновременно писать в одну ячейку памяти не могут, только последовательно (шина то — одна).
Re[17]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 12:56
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Не проц, а компилятор, и не в кеше, а в регистре.


Т.е. это
Автор: sysenter
Дата: 06.09.11
написано неправильно?
Re[16]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 13:03
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Пентиум читает/пишет целыми кеш-лайнами. Которые могут быть и 8 байт, и 16, и 32 и даже 64, в зависимости от модели процессора.


В кеш проц может блоками прочитать из памяти т.к. принцип сосредоточенности во времени никто не отменял и именно так и происходит.
Мы же говорим про атомарность операций над простыми данными размером — 2 или 4 байта. Операции над ними тот же инкремент происходят в регистре, если данные не выровнены в регистр поместить данные за одно обращение нельзя.
Или нет? Отчего тогда падение производительности на операциях с не выровненными данными?
Re[15]: поясните про volatile ?
От: Jolly Roger  
Дата: 06.09.11 13:03
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, 23W, Вы писали:


23W>>Атомарность операций 1 и 2 гарантируется архитектурой, а чтобы эта гарантия не была испорчена оптимизирующим компиляторам — нужна директива volatile переде переменными (и только для этого).

23W>>Правильно ?

Pzz>Отцы, вы забываете про то, что процессор может изменить порядок фактического обращения к памяти — по сравнению с ассемблерным кодом, а даже не сишным. При этом если "смотреть" с одного ядра, то для x86-х процессоров гарантируется, что вы этого не заметите. А вот если смотреть на ту же память с соседнего ядра, то можете и заметить.


Да, но это уже другой вопрос Для его решения существуют барьеры, volatile тут ни при чём

Pzz>В общем, если не хотите приключений на собственную ж..., лучше предохраняться использовать предназначенные для этого атомарные операции и/или примитивы синхронизации.


Так проще, но не всегда лучше.
"Нормальные герои всегда идут в обход!"
Re[15]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:05
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Volatile только подавляет оптимизацию работы с переменной в компиляторе. Т.е., везде, где у тебя выполняются какие-то действия с такой переменной, компилятор будет честно вставлять операции чтения/записи в оперативную память, даже если у него под рукой будет регистр с значением этой переменной. У MSVC есть дополнительная плюшка — действие с volatile переменной (чтение или запись) является барьером для других операций такого же типа (чтение или запись). Т.е., компилятор не поменяет их местами.


Любой вменяемый компилятор обладает этой "плюшкой".

И кстати, в отношении любых нелокальных переменных (а не только volatile) любой вызов не-inline функции обладает тем же эффектом: компилятор же не может знать, имеет эта функция доступ к этим переменным, или не имеет, и поэтому предполагает худшее. Благодаря этому данные, защищенные mutex'ом, не обязательно делать volatile: вызовы функций, захватывающих/освобождающих mutex заодно заставят компилятор упорядочить обращения к данным.
Re[16]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 13:06
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

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


Pzz>>Здравствуйте, 23W, Вы писали:


23W>>>Атомарность операций 1 и 2 гарантируется архитектурой, а чтобы эта гарантия не была испорчена оптимизирующим компиляторам — нужна директива volatile переде переменными (и только для этого).

23W>>>Правильно ?

Pzz>>Отцы, вы забываете про то, что процессор может изменить порядок фактического обращения к памяти — по сравнению с ассемблерным кодом, а даже не сишным. При этом если "смотреть" с одного ядра, то для x86-х процессоров гарантируется, что вы этого не заметите. А вот если смотреть на ту же память с соседнего ядра, то можете и заметить.


JR>Да, но это уже другой вопрос Для его решения существуют барьеры, volatile тут ни при чём

Да нет же, это все тот же вопрос! Как изменение порядка фактического обращения к памяти может разрушить атомарность простых операций чтения и записи для выровненных данных ? Это важно!
И если проц. эту атомарность разрушает — как именно, конкретно с этим бороться! Какие функции API, какие приемы ?


Pzz>>В общем, если не хотите приключений на собственную ж..., лучше предохраняться использовать предназначенные для этого атомарные операции и/или примитивы синхронизации.

JR>Так проще, но не всегда лучше.
Дайте лучшее решение.
Re[16]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 13:12
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Любой вменяемый компилятор обладает этой "плюшкой".


Ну, я это подозреваю, но под рукой только MSVC разных версий.
Имею скафандр — готов путешествовать!
Re[19]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 13:12
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>У тебя неверное представление об архитектуре интеловских процессоров.

RB>Все, на самом деле, не так.

Если DMA изменит значение volatile переменной, а она у одного ядра закешированна в не разделяемом кеше L1, как это разруливается?
Re[18]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:14
Оценка:
Здравствуйте, sysenter, Вы писали:

Pzz>>Не проц, а компилятор, и не в кеше, а в регистре.


S>Т.е. это
Автор: sysenter
Дата: 06.09.11
написано неправильно?


Неправильно.
Re[15]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 13:17
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Volatile только подавляет оптимизацию работы с переменной в компиляторе. Т.е., везде, где у тебя выполняются какие-то действия с такой переменной, компилятор будет честно вставлять операции чтения/записи в оперативную память, даже если у него под рукой будет регистр с значением этой переменной.


Подожди, вот я написал, что проц не хранит volatile переменную в неразделяемом кеше, а ты мне написал что я не разбираюсь в архитектуре процов intel. Теперь сам пишешь, что операции чтения/записи с volatile переменными происходят в оперативной памяти. Так где же правда?
Re[20]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 13:18
Оценка:
Здравствуйте, sysenter, Вы писали:

S>Если DMA изменит значение volatile переменной, а она у одного ядра закешированна в не разделяемом кеше L1, как это разруливается?


Вам нужно понять одну простую вещь.
Процессор, ядра, кеш, и прочее железо "понятия не имеют" о слове volatile.
На участках памяти, которые выделяются под переменные, слово volatile никак не влияет.
Имею скафандр — готов путешествовать!
Re[21]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 13:20
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Вам нужно понять одну простую вещь.

RB>Процессор, ядра, кеш, и прочее железо "понятия не имеют" о слове volatile.
RB>На участках памяти, которые выделяются под переменные, слово volatile никак не влияет.

Тогда хотелось бы получить ответ на это
Автор: sysenter
Дата: 06.09.11
Re[17]: поясните про volatile ?
От: 23W http://kyselgov.pp.ua/
Дата: 06.09.11 13:22
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, 23W, Вы писали:


Pzz>>>В общем, если не хотите приключений на собственную ж..., лучше предохраняться использовать предназначенные для этого атомарные операции и/или примитивы синхронизации.

23W>>Скажите, как такое поведение процессора может сказаться на атомарности операции записи или чтения выровренных данных. Ведь два процессора одновременно писать в одну ячейку памяти не могут, только последовательно (шина то — одна).

Pzz>В одном потоке вы пишете: flag = true; i = 5. Другой поток, на другом процессоре, может увидеть на мгновение, что i уже 5, а flag все еще false. Атомарности операций это не противоречит, но вот порядок исполнения — другой. А если то же самое делать через InterlockedXXX(), или под мьютексом, то порядок будет правильный, такой же, как в тексте.


Спасибо, это понятно. Я пока говорил только о использовании одной переменной (в качестве флаг, события, симофора, мьютекса или другого), пока пришел к выводу что volatile bool или volatile LONG и т.п. могут так использоваться (до тех пор пока компилятор выравнивает стуркутры внутри кода на границы в 4 или 8 байт, зависит от x86 или x64). Для этого к ним могу применятся только примитивные операции чтения или записи.
Например такая переменная volatile LONG служит событием, где какой-либо поток проверяет ее на >0 чтобы начать обрабатывать данные, а другой поток взводит ее в 1 когда подготовил данные для первого потока. Изначально же эта переменная была 0.
Re[17]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 13:23
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>В одном потоке вы пишете: flag = true; i = 5. Другой поток, на другом процессоре, может увидеть на мгновение, что i уже 5, а flag все еще false. Атомарности операций это не противоречит, но вот порядок исполнения — другой. А если то же самое делать через InterlockedXXX(), или под мьютексом, то порядок будет правильный, такой же, как в тексте.


1. ТС спрашивает про атомарность, а не про синхронизацию или порядок работы с памятью.

2. То, что interlocked-операция работает как барьер — это фича реализации процессора ("расслабленность").
Вполне могут быть архитектуры, где это не так, и требуются "настоящие" барьеры.

3. Интеловские процессоры достаточно "строгие" в смысле переупорядочивания.
В частности, твой пример flag=true; i=5; будет работать корректно — все другие ядра "увидят" изменения в правильном порядке.
Имею скафандр — готов путешествовать!
Re[19]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 13:25
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Пентиум умеет синхронизировать кеши между процессорами/ядрами так, что программисту это незаметно. Это называется "когерентный кэш". И да, они между собой переговариваются, чтобы знать, когда синхронизировать кэш


Про то, что ядра синхронизируют кеши я вкурсе. Как быть с DMA если он незаметно в оперативке поменяет значение volatile переменной или если эта переменная есть на самом деле участок памяти отображённый на устройство? Как проц узнает, что значение в памяти поменялось, если оно меняется при каждом считывании?
Re[16]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 13:27
Оценка:
Здравствуйте, sysenter, Вы писали:

RB>>Volatile только подавляет оптимизацию работы с переменной в компиляторе. Т.е., везде, где у тебя выполняются какие-то действия с такой переменной, компилятор будет честно вставлять операции чтения/записи в оперативную память, даже если у него под рукой будет регистр с значением этой переменной.


S>Подожди, вот я написал, что проц не хранит volatile переменную в неразделяемом кеше, а ты мне написал что я не разбираюсь в архитектуре процов intel. Теперь сам пишешь, что операции чтения/записи с volatile переменными происходят в оперативной памяти. Так где же правда?


Правда — в силе.

Ты пишешь про хранение значений volatile-переменных в кеше процессора.
Я говорю про генерацию кода компилятором.

Где противоречие?
Имею скафандр — готов путешествовать!
Re[17]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:32
Оценка:
Здравствуйте, sysenter, Вы писали:

Pzz>>Пентиум читает/пишет целыми кеш-лайнами. Которые могут быть и 8 байт, и 16, и 32 и даже 64, в зависимости от модели процессора.


S>В кеш проц может блоками прочитать из памяти т.к. принцип сосредоточенности во времени никто не отменял и именно так и происходит.


Че такое "принцип сосредоточенности во времени"?

S>Мы же говорим про атомарность операций над простыми данными размером — 2 или 4 байта. Операции над ними тот же инкремент происходят в регистре, если данные не выровнены в регистр поместить данные за одно обращение нельзя.


Аппаратура работает блоками размера N. Если данные не выровненны на границу блока, то да, одним обращением не обойдешься. N разный в зависимости от модели процессора и от места в нем (т.е., для работы с внешней памятью и для пересылок по внутренней шине N разный). Но я не уверен, что в современном процессоре есть хоть одно место, где N равен 4

S>Или нет? Отчего тогда падение производительности на операциях с не выровненными данными?


А она есть на современных процессорах?
Re[20]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:35
Оценка:
Здравствуйте, sysenter, Вы писали:

RB>>У тебя неверное представление об архитектуре интеловских процессоров.

RB>>Все, на самом деле, не так.

S>Если DMA изменит значение volatile переменной, а она у одного ядра закешированна в не разделяемом кеше L1, как это разруливается?


На x86 — путем "переговоров" между процессором и контроллером шины, полностью автоматизированных. На более других процессорах может и програмно разруливаться.
Re[17]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 13:36
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Ты пишешь про хранение значений volatile-переменных в кеше процессора.

RB>Я говорю про генерацию кода компилятором.
RB>Где противоречие?

Противоречие, есть устройство (например датчик температуры реактора АЭС) с которого переменная volatile позволяет читать данные атомарно по одному byte или char за раз и каждый раз при чтении получаем новые данные.
Кешировать тут в кеше проца не просто бессмыслено, но и опасно. Если верить тебе то проц будет хранить значение этой переменной в кеше. Или не будет?
Re[18]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:42
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>2. То, что interlocked-операция работает как барьер — это фича реализации процессора ("расслабленность").

RB>Вполне могут быть архитектуры, где это не так, и требуются "настоящие" барьеры.

Это фича не процессора, а того API, в котором определены эти interlocked операции. Hint: вендовые InterlockedXXX() будут работать как барьер на любой архитектуре, где работает венда и понятие барьера имеет хоть какой-то физический смысл. А вот во что они превратятся "в ассемблерном виде", зависит от архитектуры.

RB>3. Интеловские процессоры достаточно "строгие" в смысле переупорядочивания.

RB>В частности, твой пример flag=true; i=5; будет работать корректно — все другие ядра "увидят" изменения в правильном порядке.

Нет. И кроме того, что об этом прямо написано в интеловском мануале, я имел счастье в этом на опыте убедиться (отлаживать это место было весело).
Re[19]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 13:46
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Это фича не процессора, а того API, в котором определены эти interlocked операции. Hint: вендовые InterlockedXXX() будут работать как барьер на любой архитектуре, где работает венда и понятие барьера имеет хоть какой-то физический смысл. А вот во что они превратятся "в ассемблерном виде", зависит от архитектуры.


Ок.

RB>>3. Интеловские процессоры достаточно "строгие" в смысле переупорядочивания.

RB>>В частности, твой пример flag=true; i=5; будет работать корректно — все другие ядра "увидят" изменения в правильном порядке.

Pzz>Нет. И кроме того, что об этом прямо написано в интеловском мануале, я имел счастье в этом на опыте убедиться (отлаживать это место было весело).


А покажи, где это написано?
Имею скафандр — готов путешествовать!
Re[18]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 13:47
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Че такое "принцип сосредоточенности во времени"?


Если была работа в некоторый момент времени с данными (чтение, запись) то велика вероятность, что в самом ближайшем будущем будет ещё работа с данными в том же месте или рядом.

Pzz>Аппаратура работает блоками размера N.


Вот из-за принципа сосредоточенности во времени и работает блоками т.к. дешевле прочитать сразу блок размером N чем по N раз читать по байту.

Pzz>Если данные не выровненны на границу блока, то да, одним обращением не обойдешься. N разный в зависимости от модели процессора и от места в нем (т.е., для работы с внешней памятью и для пересылок по внутренней шине N разный). Но я не уверен, что в современном процессоре есть хоть одно место, где N равен 4


Мне нужно прочитать 4-х байтовое значение, контролер доступа к памяти прочитал блок размером N (если не ошибаюсь 4096) и что дальше?
Он его кладёт в кеш и потом проц из кеша извлекает 4-х байтовое значение или проц сразу получает 4-х байтовое значение, а блок данных только после этого кладётся в кеш? Логично предположить, что второй вариант более вероятен, отсюда если данные выровнены то проц тратит меньше тактов чтобы поместить значение в регистр.

Pzz>А она есть на современных процессорах?


А разве нет или я что-то пропустил?
Re[21]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 13:53
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>DMA не проходит мимо чипсета. Чипсет умеет общаться с процессором.

Pzz>Если устройство отображается на память, есть 2 варианта: либо пометить соответствующие страницы, как некешируемые, либо програмно сбрасывать кеш до/после изменения данных, в зависимости от направления передачи.

Ок, вопрос снят.
Re[19]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 13:53
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Нет. И кроме того, что об этом прямо написано в интеловском мануале, я имел счастье в этом на опыте убедиться (отлаживать это место было весело).


Нет, ты это серъезно?
Вот мануал
"Intel 64 and IA-32 Architectures Software Developers Manual.3A.System Programming Guide.Part1.pdf"
Пункт 8.2.3.2

Example 8-1. Stores Are Not Reordered with Other Stores
---------------------------------
Processor 0 | Processor 1
---------------------------------
mov [ _x], 1 | mov r1, [ _y]
mov [ _y], 1 | mov r2, [ _x]
---------------------------------
Initially x == y == 0
r1 == 1 and r2 == 0 is not allowed
---------------------------------


Это не твой пример?
Имею скафандр — готов путешествовать!
Re[20]: поясните про volatile ?
От: Jolly Roger  
Дата: 06.09.11 13:54
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>>>В частности, твой пример flag=true; i=5; будет работать корректно — все другие ядра "увидят" изменения в правильном порядке.


Pzz>>Нет. И кроме того, что об этом прямо написано в интеловском мануале, я имел счастье в этом на опыте убедиться (отлаживать это место было весело).


RB>А покажи, где это написано?


Вот в этой теме
Автор: tealex
Дата: 22.10.09
обсуждался такой случай. Судя по всему, не связынные по данным или управлению операции могут оказаться на разных конвейерах, и это в некоторых случаях может изменить порядок выполнения операций.
"Нормальные герои всегда идут в обход!"
Re[20]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 13:57
Оценка:
Здравствуйте, rus blood, Вы писали:

Pzz>>Нет. И кроме того, что об этом прямо написано в интеловском мануале, я имел счастье в этом на опыте убедиться (отлаживать это место было весело).


RB>А покажи, где это написано?


Берешь с интеловского сайыа мануал по любому современному интеловскому процессору, и ищешь. Мне понадобилось где-то с полчаса, чтобы найти. Закладку я, естественно, не поставил
Re[21]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 14:01
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Вот в этой теме
Автор: tealex
Дата: 22.10.09
обсуждался такой случай. Судя по всему, не связынные по данным или управлению операции могут оказаться на разных конвейерах, и это в некоторых случаях может изменить порядок выполнения операций.


Это вовсе не тот случай.
Это случай последовательных store-load по разным адресам, который как раз и может быть re-ordered процессором.
И не надо было столько копий ломать, когда это явно сказано в мануале:
8.2.3.4 Loads May Be Reordered with Earlier Stores to Different Locations


У Pzz написаны две подряд store-операции.
Имею скафандр — готов путешествовать!
Re[21]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 14:02
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Берешь с интеловского сайыа мануал по любому современному интеловскому процессору, и ищешь. Мне понадобилось где-то с полчаса, чтобы найти. Закладку я, естественно, не поставил


Мне не надо его брать с сайта.
Мануал есть у меня под рукой, и я перечитываю его постоянно 50 раз в секунду.
Процессор НЕ переупорядочивает последовательные store-store операции.
Имею скафандр — готов путешествовать!
Re[19]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 14:04
Оценка:
Здравствуйте, sysenter, Вы писали:

Pzz>>Аппаратура работает блоками размера N.


S>Вот из-за принципа сосредоточенности во времени и работает блоками т.к. дешевле прочитать сразу блок размером N чем по N раз читать по байту.


Работает блоками потому, что тупо мегагерцы наращивать уже больше не получается. Остается наращивать параллелизм.

S>Мне нужно прочитать 4-х байтовое значение, контролер доступа к памяти прочитал блок размером N (если не ошибаюсь 4096) и что дальше?

S>Он его кладёт в кеш и потом проц из кеша извлекает 4-х байтовое значение или проц сразу получает 4-х байтовое значение, а блок данных только после этого кладётся в кеш? Логично предположить, что второй вариант более вероятен, отсюда если данные выровнены то проц тратит меньше тактов чтобы поместить значение в регистр.

Я в таких деталях не знаю. Но все значительно сложнее. Процессору надо для какой-то операции 4 байта данных. В кеше он поискал и не нашел. Он ставит в очередь запрос на обращение к памяти, и насколько может, едет дальше. Когда-нибудь там запрос к памяти чем-нибудь закончится, тогда процессор вернется к отложенной операции (по мере готовности ALU, а они может оказаться и занятым в момент, когда данные пришли), и что-нибудь с ней сделает. Попадают ли данные в регистр через промежуточную запись в кеш, или сразу туда и туда попадают, мне неизвестно. Но шина внутри самого процессора тоже, насколько я понимаю, не 4-байтная. Поэтому если эти 4 байта попадают в одну операцию шины, совсем не факт, что для процессора важно, как они выровненны.

S>А разве нет или я что-то пропустил?


Я слышал краем уха, что уже нет. За достоверность не поручусь.
Re[22]: поясните про volatile ?
От: Jolly Roger  
Дата: 06.09.11 14:04
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Это вовсе не тот случай.

RB>Это случай последовательных store-load по разным адресам, который как раз и может быть re-ordered процессором.
RB>И не надо было столько копий ломать, когда это явно сказано в мануале:
RB>8.2.3.4 Loads May Be Reordered with Earlier Stores to Different Locations

А это из какого мануала?
"Нормальные герои всегда идут в обход!"
Re[20]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 14:09
Оценка:
Здравствуйте, rus blood, Вы писали:

Pzz>>Нет. И кроме того, что об этом прямо написано в интеловском мануале, я имел счастье в этом на опыте убедиться (отлаживать это место было весело).


RB>Нет, ты это серъезно?


Поверь на слово, а? Или давай поспорим на $100. Ну скучное это занятие, мануал читать, неохота мне сейчас забесплатно этим заниматься

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

И да, речь идет о более-менее современных процессорах. Что там было во времена 80486, я особо не интересовался
Re[20]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 14:11
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Работает блоками потому, что тупо мегагерцы наращивать уже больше не получается. Остается наращивать параллелизм.


Оно всегда блоками происходило, чтение/запись, сколько себя помню.
Потому, что на время чтения/записи происходит блокирование линии и если гипотетически предположить, что можно было бы читать по байту, а не по блоку то большая часть времени тратилась бы на блокирование/разблокирование.

Pzz>Поэтому если эти 4 байта попадают в одну операцию шины, совсем не факт, что для процессора важно, как они выровненны.

Pzz>Я слышал краем уха, что уже нет. За достоверность не поручусь.

Надеюсь просвещённая общественность подскажет, как оно на самом деле.
Re[21]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 14:15
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Поверь на слово, а? Или давай поспорим на $100. Ну скучное это занятие, мануал читать, неохота мне сейчас забесплатно этим заниматься


Pzz>Там написано, что каждое отдельное ядро само с собой self-consistent. Т.е., глядя с одного ядра, reordering заметить нельзя (это не значит, что его нет, но если следующая операция зависит от предыдущей, процессор сам ее притормозит, как надо). А вот между ядрами такого удобства нет.


Pzz>И да, речь идет о более-менее современных процессорах. Что там было во времена 80486, я особо не интересовался


Не поверю, да и вера здесь не причем.
Мне эта тема важна для моей работы.

Что касается 486, то насколько я понял, со временем (с P6, кажется), процессор стал только более строгий.
Имею скафандр — готов путешествовать!
Re[22]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 14:17
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Мне не надо его брать с сайта.

RB>Мануал есть у меня под рукой, и я перечитываю его постоянно 50 раз в секунду.
RB>Процессор НЕ переупорядочивает последовательные store-store операции.

Вот представь себе, есть 3 переменные: a, b и c. a и c — соседи, живут в одном кеш-лайне и по вечерам ходят друг к другу на чай. А b живет в другом кеш-лайне и с ними не дружит.

Берем и пишем: a = 1; b = 2; c = 3; Что, по-твоему, процессор тот кеш-лайн, где живут a и c, два раза в память скинет?
Re[23]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 14:27
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Вот представь себе, есть 3 переменные: a, b и c. a и c — соседи, живут в одном кеш-лайне и по вечерам ходят друг к другу на чай. А b живет в другом кеш-лайне и с ними не дружит.

Pzz>Берем и пишем: a = 1; b = 2; c = 3; Что, по-твоему, процессор тот кеш-лайн, где живут a и c, два раза в память скинет?

А что, кем-то запрещено скидывать кеш-линии несколько раз в память?
И причем тут скидывание кеш-линий в память, и видимость изменений на другом ядре?

В данном примере.
После a=1 у первого ядра будет эксклюзивный доступ к первой кеш-линии, у второго ядра эта кеш-линия будет отмечена как dirty.
После b=2 то же самое будет со второй кеш-линией.

Теперь другое ядро читает b, т.е. происходит синхронизация второй кеш-линии.
Далее второе ядро читает переменную a, и выполняется синхронизация первой кеш-линии.

Если второе ядро видит в b значение 2, значит вторая кеш-линия уже изменена первым ядром.
Процессор гарантирует, что второе ядро увидит измененную версию первой кеш-линии (т.е. увидит, что a==1, и никак иначе).
Имею скафандр — готов путешествовать!
Re[24]: поясните про volatile ?
От: sysenter  
Дата: 06.09.11 14:31
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>В данном примере.

RB>После a=1 у первого ядра будет эксклюзивный доступ к первой кеш-линии, у второго ядра эта кеш-линия будет отмечена как dirty.
RB>После b=2 то же самое будет со второй кеш-линией.

В мануалах интела с такой детализацией описывают синхронизацию кеша? Где-то я читал, что гарантируется только синхронизация кеша, а механизм скрыт.
Re[5]: поясните про volatile ?
От: Erop Россия  
Дата: 06.09.11 14:36
Оценка:
Здравствуйте, 23W, Вы писали:

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


Пример 1
Архитектура не умеет адресоваться к байтам. Только к словам. К байтам аддресация сделана софтверно, например через здвиги там всякие и т. п.

Пример 2
Аппаратура устроена так, что при попытке одновременной записи по одноу адресу из двух процессоров случается авост.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[24]: поясните про volatile ?
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.09.11 17:29
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>А что, кем-то запрещено скидывать кеш-линии несколько раз в память?

RB>И причем тут скидывание кеш-линий в память, и видимость изменений на другом ядре?

ОК. Значит, я нарвался на то, что чтения и записи могут быть reordered (пришлось посмотреть мануал, ordering чтений/записей процессор гарантирует только если в одно и то же место обращаться).

Ужасно лень подымать change log большого проекта, искать там соответствующий патч и вспоминать, что именно от патчит
Re: поясните про volatile ?
От: 11molniev  
Дата: 06.09.11 17:32
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Уже несколько раз читал в разных местах, что volatile директива перед переменной не гарантирует атомарность операции с самой переменной, при работе с ней в несколько потоков. Так ли это ?

23W>Действительно, разве изменение volatile bool или volatile BYTE переменной может быть не атомарной ? ведь это примитивный байтовый тип изменяемый за одну asm операцию. Или все же нужно менять содержимое таких переменных через Intelock???

Иногда правильный ответ гораздо проще получить на практике, чем читать весь тот срач что устроили "специалисты" (а правильно вам подсказывают только в последних ветках)

#define MAX_THREAD 4
#define MAX_INC 10000000

/* bool == BYTE == char */
long a = 0; /*char a = 0; */
volatile long b = 0; /*volatile char b = 0;*/
long c = 0;

DWORD WINAPI start(LPVOID lpThreadParameter)
{
    int i = 0;
    for (i = 0; i < MAX_INC; i++)
    {
        a++;
        b++;
        InterlockedIncrement(&c);
    }
}

int main(int argc, char *argv[])
{
    HANDLE h[MAX_THREAD];
    DWORD n = 0;
    int i = 0;

    for (i = 0; i < MAX_THREAD; i++)  {
        h[i] = CreateThread(NULL, 0, start, NULL, 0, &n);
        if ( INVALID_HANDLE_VALUE == h[i]) ExitProcess(-1);
    }
    WaitForMultipleObjects(MAX_THREAD, &h, TRUE, INFINITE);
    printf("%i \t a = %i \t b = %i \t c = %i", MAX_THREAD*MAX_INC, a, b, c);
    /*printf("%i \t a = %i \t b = %i \t c = %i", 0xff & (MAX_THREAD*MAX_INC), a, b, (0xff & c) ); */

    getchar();
    return 0;
}


ЗЫ. Обратный тест (если с volatile long было верное значение — некоректен) — по неправильной работе в частном случае можно утверждать неправильность работы в целом. Но по правильной работе в частном случае невозможно утверждать о правильной работе в целом.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.