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

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


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

Как данные выровнены внутри кеш-лайна, процессору все равно. Если данные пересекают границу кеш-лайна, насколько я понимаю, аппаратура не гарантирует атомарного обращения, чего бы не было написано в программе.
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[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:54
Оценка: -2
Здравствуйте, 23W, Вы писали:

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

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

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

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


Т.е. это
Автор: sysenter
Дата: 06.09.11
написано неправильно?
Re[18]: поясните про volatile ?
От: rus blood Россия  
Дата: 06.09.11 12:58
Оценка: +2
Здравствуйте, sysenter, Вы писали:

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

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

У тебя неверное представление об архитектуре интеловских процессоров.
Все, на самом деле, не так.
Имею скафандр — готов путешествовать!
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[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[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[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:13
Оценка: 4 (1)
Здравствуйте, sysenter, Вы писали:

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

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

Пентиум умеет синхронизировать кеши между процессорами/ядрами так, что программисту это незаметно. Это называется "когерентный кэш". И да, они между собой переговариваются, чтобы знать, когда синхронизировать кэш
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
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.