volatile у переменной класса
От: Vet  
Дата: 09.01.05 11:26
Оценка:
В объекте класса есть переменная, которая используется двумя потоками.
Один из потоков иногда меняет ее значение.
Есть ли необходимость в этом случае делать переменную как volatile.
И зависит ли ответ от того, сздан ли объект класса на стеке или в динамической памяти.

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

11.01.05 07:45: Перенесено модератором из 'C/C++. Прикладные вопросы' — Павел Кузнецов
Re: volatile у переменной класса
От: MaximE Великобритания  
Дата: 09.01.05 18:55
Оценка: 9 (1) +1 -4
Vet wrote:

> В объекте класса есть переменная, которая используется двумя потоками.

> Один из потоков иногда меняет ее значение.
> Есть ли необходимость в этом случае делать переменную как volatile.
> И зависит ли ответ от того, сздан ли объект класса на стеке или в динамической памяти.
>
> Вопрос вызван тем, что у Рихтера прочитал, что если глобальная переменная используется
> разными потоками, то она обязана быть volatile. Вот меня и рабирают сомнения нужно ли
> тоже самое делать для переменных(членов) класса.

Рихтер ошибался.

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

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[2]: volatile у переменной класса
От: Dr.Gigabit  
Дата: 09.01.05 21:16
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Vet wrote:


>> В объекте класса есть переменная, которая используется двумя потоками.

>> Один из потоков иногда меняет ее значение.
>> Есть ли необходимость в этом случае делать переменную как volatile.
>> И зависит ли ответ от того, сздан ли объект класса на стеке или в динамической памяти.
>>
>> Вопрос вызван тем, что у Рихтера прочитал, что если глобальная переменная используется
>> разными потоками, то она обязана быть volatile. Вот меня и рабирают сомнения нужно ли
>> тоже самое делать для переменных(членов) класса.

ME>Рихтер ошибался.


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


Не могли бы вы более подробно пояснить, зачем тогда вообще использовать volatile? Всегда думал, что volatile обозначает, что данные могут изменяться без ведома компилятора(в том числе и с помощью многопоточности). Т.е. компилятор не должен делать никахих предположений о значении переменной, в частности, в целях оптимизации.
... << RSDN@Home 1.1.4 @@subversion >>
Re[3]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 09.01.05 21:47
Оценка: 2 (1)
Dr.Gigabit wrote:

[]

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


http://rsdn.ru/forum/?mid=922675
Автор: MaximE
Дата: 29.11.04


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re: volatile у переменной класса
От: c-smile Канада http://terrainformatica.com
Дата: 10.01.05 05:40
Оценка: 18 (1) -2
Здравствуйте, Vet, Вы писали:

Vet>В объекте класса есть переменная, которая используется двумя потоками.

Vet>Один из потоков иногда меняет ее значение.
Vet>Есть ли необходимость в этом случае делать переменную как volatile.
Vet>И зависит ли ответ от того, сздан ли объект класса на стеке или в динамической памяти.

Vet>Вопрос вызван тем, что у Рихтера прочитал, что если глобальная переменная используется

Vet>разными потоками, то она обязана быть volatile. Вот меня и рабирают сомнения нужно ли
Vet>тоже самое делать для переменных(членов) класса.

Да, обязательно, иначе оптимизатор тебе такого наворотит — не обрадуешься.

The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something other than statements, such as the operating system, the hardware, or a concurrently executing thread.


Желательно еще установку этой переменной выполнять с помощью InterlockedExchange.
Собственно так как эта функция объявлена как

LONG InterlockedExchange(
  LPLONG volatile Target, // value to exchange
  LONG Value              // new value
);


без объявления volatile у тебя ничего и не получится.
Re[2]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 10.01.05 08:14
Оценка:
c-smile wrote:

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

>
> Vet>В объекте класса есть переменная, которая используется двумя потоками.
> Vet>Один из потоков иногда меняет ее значение.
> Vet>Есть ли необходимость в этом случае делать переменную как volatile.
> Vet>И зависит ли ответ от того, сздан ли объект класса на стеке или в динамической памяти.
>
> Vet>Вопрос вызван тем, что у Рихтера прочитал, что если глобальная переменная используется
> Vet>разными потоками, то она обязана быть volatile. Вот меня и рабирают сомнения нужно ли
> Vet>тоже самое делать для переменных(членов) класса.
>
> Да, обязательно, иначе оптимизатор тебе такого наворотит — не обрадуешься.
>

> The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something other than statements, such as the operating system, the hardware, or a concurrently executing thread.


Это не так. Кусок не из стандарта, а наверное, из MSDN. Почитайте про sequence points.

> Желательно еще установку этой переменной выполнять с помощью InterlockedExchange.

> Собственно так как эта функция объявлена как
>
>
> LONG InterlockedExchange(
>   LPLONG volatile Target, // value to exchange
>   LONG Value              // new value
> );
>

>
> без объявления volatile у тебя ничего и не получится.

Наверное, LPLONG volatile* (star) Target? Почему же без volatile не получиться? Как и в функцию, которая принимает указатель на константный объект мы можем передать указатель на неконстнантный объект, но но не наооборот, так и в функциию принимающую указатель на волатильный, мы можем передать указатель на неволатильный объект.

Вообще, квалификатор volatile у всех Interlocked* функций абсолютно бесполезен, и даже вреден, так как сбивает людей с толку. Так как это ф-ции, то они представляют для компилятора sequence points. После sequence points, компилятор обязан перечитывать значения переменных из памяти, неважно, volatile ли, const ли, или это переменная без cv-квалификатора, и оптимизатор здесь не может ничего сделать.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[3]: volatile у переменной класса
От: emusic Франция https://software.muzychenko.net/ru
Дата: 10.01.05 13:48
Оценка: 3 (1) +1
Здравствуйте, MaximE, Вы писали:

ME>c-smile wrote:


>> The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something other than statements, such as the operating system, the hardware, or a concurrently executing thread.

>> [/q]

ME>Это не так. Кусок не из стандарта, а наверное, из MSDN. Почитайте про sequence points.


Sequence points — это вообще из другой оперы. Sequence point — место, где заканчиваются побочные эффекты, и не более того. Причем относится это исключительно к имеющему место "потоку выполнения", и к параллельным потокам отношения не имеет. А вот при наличии volatile при каждом обращении к такому объекту формируется sequence point. Прохождение sequence point отнюдь не гарантирует, что состояния всех объектов в этой точке будут непременно отражены в памяти — это гарантируется только для volatile-объектов.

ME>Вообще, квалификатор volatile у всех Interlocked* функций абсолютно бесполезен, и даже вреден, так как сбивает людей с толку. Так как это ф-ции, то они представляют для компилятора sequence points.


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

ME> После sequence points, компилятор обязан перечитывать значения переменных из памяти, неважно, volatile ли, const ли, или это переменная без cv-квалификатора


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

Простейший пример:

void f (int &a, int &b) {
  if (!a) {
    b = a;
  }
}


При включенной оптимизации многие компиляторы (например, VC++ 6.0) сгенерируют только один опрос переменной a — в проверке условия. Для присваивания будет сгенерирован явный нуль. Если к a добавить volatile — будет сгенерировано повторное чтение из памяти. И совершенно правильно.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[4]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 10.01.05 17:06
Оценка:
emusic wrote:

>>> The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something other than statements, such as the operating system, the hardware, or a concurrently executing thread.

>>> [/q]
>
> ME>Это не так. Кусок не из стандарта, а наверное, из MSDN. Почитайте про sequence points.
>
> Sequence points — это вообще из другой оперы. Sequence point — место, где заканчиваются побочные эффекты, и не более того. Причем относится это исключительно к имеющему место "потоку выполнения", и к параллельным потокам отношения не имеет.

Именно так. Стандарт вообще не упоминает никаких потоков кроме единственного control flow и еще упоминают обработчики сигналов, для которых собственно и был придуман volatile.

И это проблема стандарта, над которой уже работают умы. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1680.pdf

> А вот при наличии volatile при каждом обращении к такому объекту формируется sequence point.


Именно так.

> Прохождение sequence point отнюдь не гарантирует, что состояния всех объектов в этой точке будут непременно отражены в памяти — это гарантируется только для volatile-объектов.


Я этого и не утверждал, как раз я утверждаю обратное.

Все что я утверждал, что volatile бесполезен, потому, что он не сделает не потокобезопасный код потокобезопасным. Потокобезопасность достигается использованием соответствующих примитивов синхронизации. Использование любого примитива синхронизации в POSIX и win32 является вызовом ф-ции. Вызов ф-ции — sequence point. Если у тебя уже есть sequence points вокруг защищаемых данных, зачем тогда volatile?

> ME>Вообще, квалификатор volatile у всех Interlocked* функций абсолютно бесполезен, и даже вреден, так как сбивает людей с толку. Так как это ф-ции, то они представляют для компилятора sequence points.

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

Это так только по случайному стечению обстоятельств на IA32. volatile имеет влияние лишь на код, генерируемый компилятором. На переупорядочивание инструкций процессором он не имеет никакого влияния. Именно по этой причине на всех современных RISC процессорах, а также на IA64, тебе придется использовать барьеры памяти чтобы прочитать актуальное значение.

> ME> После sequence points, компилятор обязан перечитывать значения переменных из памяти, неважно, volatile ли, const ли, или это переменная без cv-квалификатора

>
> С чего бы он вдруг стал обязан? Компилятор обязан лишь обеспечить последовательное выполнение заданных действий в рамках одного потока исполнения. Для взаимодействия с "внешними" процессами и существует volatile.

С тем, что состояние программы после sequence point is indeterminate.

> Простейший пример:

>
>
> void f (int &a, int &b) {
>   if (!a) {
>     b = a;
>   }
> }
>

>
> При включенной оптимизации многие компиляторы (например, VC++ 6.0) сгенерируют только один опрос переменной a — в проверке условия. Для присваивания будет сгенерирован явный нуль.

Здесь именно простейший пример: нет вызовов ф-ций, компилятор видит весь контекст и плевал на sequence points. Добавим вызов ф-ции.

#include <cstdio>

void f1(int &a, int &b)
{
     if (!a)
     {
         b = a;
     }
}

void f2(int volatile &a, int &b)
{
     if (!a)
     {
         b = a;
     }
}

void f3(int &a, int &b)
{
     if (!a)
     {
         printf("0x%08x\n", &a);
         b = a;
     }
}

int main(int ac, char** av)
{
     int b;
     f1(ac, b);
     f2(ac, b);
     f3(ac, b);
     return b;
}


MS VC 7.1

Command Lines    

Creating temporary file "c:\windows\temp\Vad43A.bs" with contents
[
/c  /Ox /Og /Ob2 /Oi /Ot /Oy /G6 /GF /FD /EHsc /ML /Zc:wchar_t /Zc:forScope /GR /Zi /nologo /W3 /Wp64 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"Release/" /Fd"Release/vc70.pdb" /Gd /TP
.\main.cpp
]
Creating command line "cl.exe @c:\windows\temp\Vad43A.bs"
Creating temporary file "c:\windows\temp\Vad43C.bs" with contents
[
/LTCG /OUT:"Release/exp.exe" /INCREMENTAL:NO /DEBUG /PDB:"Release/exp.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /TLBID:1 /MACHINE:IX86  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Release\main.obj
]
Creating command line "xilink.exe @c:\windows\temp\Vad43C.bs"


--- d:\src\exp\main.cpp --------------------------------------------------------

int main(int ac, char** av)
{
     int b;
     f1(ac, b);
00401070 8B 4C 24 04      mov         ecx,dword ptr [esp+4] ; сохранили ac в ecx
00401074 85 C9            test        ecx,ecx
00401076 75 04            jne         main+0Ch (40107Ch)
00401078 33 C0            xor         eax,eax
0040107A EB 04            jmp         main+10h (401080h)
0040107C 8B 44 24 04      mov         eax,dword ptr [esp+4] ; oops, перечетали ac, видимо такая оптимизация
     f2(ac, b);
00401080 8B 54 24 04      mov         edx,dword ptr [esp+4] ; еще раз сохранили ac в ecx
00401084 85 D2            test        edx,edx
00401086 75 04            jne         main+1Ch (40108Ch)
00401088 8B 44 24 04      mov         eax,dword ptr [esp+4] ; перечитали ac, так и должно быть, volatile
     f3(ac, b);
0040108C 85 C9            test        ecx,ecx ; используем сохраненное ac в ecx
0040108E 75 16            jne         main+36h (4010A6h)
00401090 8D 44 24 04      lea         eax,[esp+4]
00401094 50               push        eax
00401095 68 FC 60 40 00   push        offset string "0x%08x\n" (4060FCh)
0040109A E8 08 00 00 00   call        printf (4010A7h)
     return b;
0040109F 8B 44 24 0C      mov         eax,dword ptr [esp+0Ch] ; перечитали ac, так и должно быть, function call
004010A3 83 C4 08         add         esp,8
}
004010A6 C3               ret


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

> Если к a добавить volatile — будет сгенерировано повторное чтение из памяти. И совершенно правильно.


С этим никто не спорит.



Мой point: volatile бесполезен (и даже вреден) для multithreading, барьеры нужны по-любому.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 10.01.05 17:08
Оценка:
emusic wrote:

> Прохождение sequence point отнюдь не гарантирует, что состояния всех объектов в этой точке будут непременно отражены в памяти — это гарантируется только для volatile-объектов.


Это не гарантируется большинством современных процессоров.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[3]: volatile у переменной класса
От: c-smile Канада http://terrainformatica.com
Дата: 10.01.05 18:34
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Наверное, LPLONG volatile* (star) Target? Почему же без volatile не получиться? Как и в функцию, которая принимает указатель на константный объект мы можем передать указатель на неконстнантный объект, но но не наооборот, так и в функциию принимающую указатель на волатильный, мы можем передать указатель на неволатильный объект.


Нет именно так как я и написал. Это дословно из MSDN.

ME>Вообще, квалификатор volatile у всех Interlocked* функций абсолютно бесполезен....


Поверь мне (если не мне то хотя бы хедерам от WinSDK), очень полезен и стоит там по делу.

Счастливый, ты еще не "втыкался" в проблемы связанные в hyperthreading по всей видимости.
Re[5]: volatile у переменной класса
От: c-smile Канада http://terrainformatica.com
Дата: 10.01.05 18:38
Оценка:
Здравствуйте, MaximE, Вы писали:

>> Прохождение sequence point отнюдь не гарантирует, что состояния всех объектов в этой точке будут непременно отражены в памяти — это гарантируется только для volatile-объектов.


ME>Это не гарантируется большинством современных процессоров.


Т.е. ты утверждаешь что в "большинстве современных процессоров" нет операции
записи регистра в память? Или я не понял чего.
Re[5]: volatile у переменной класса
От: emusic Франция https://software.muzychenko.net/ru
Дата: 10.01.05 18:43
Оценка: -1
Здравствуйте, MaximE, Вы писали:

ME>Использование любого примитива синхронизации в POSIX и win32 является вызовом ф-ции. Вызов ф-ции — sequence point. Если у тебя уже есть sequence points вокруг защищаемых данных, зачем тогда volatile?


Абсолютной необходимости в примитивах синхронизации нет. Если один процесс записывает значения в некоторую ячейку общей памяти, а другой их оттуда читает, и доступ к ячейке на всех поддерживаемых платформах гарантированно атомарный — какой смысл в дополнительных примитивах? Достаточно лишь указать компилятору, что с объектом нужно вести себя более аккуратно, что и делает volatile.

Например, в Windows MME в описателе звукового буфера есть флажок WHDR_DONE, означающий, что драйвер завершил обработку буфера. Можно, конечно, заказать специфическое уведомление, но можно и просто опрашивать этот флажок время от времени. Что запретит компилятору перечитывать его из памяти, если весь описатель не будет объявлен с volatile?

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


ME>Это так только по случайному стечению обстоятельств на IA32.


Почему по случайному? Еще не так давно подавляющее большинство платформ работало именно так.

ME> volatile имеет влияние лишь на код, генерируемый компилятором. На переупорядочивание инструкций процессором он не имеет никакого влияния.


А зачем? Назначение volatile — влиять именно на код. Соответственно, процессор своими средствами обеспечивает определенность вычислений.

ME> Именно по этой причине на всех современных RISC процессорах, а также на IA64, тебе придется использовать барьеры памяти чтобы прочитать актуальное значение.


Именно этим может и заниматься компилятор, обрабатывая volatile.

>> ME> После sequence points, компилятор обязан перечитывать значения переменных из памяти, неважно, volatile ли, const ли, или это переменная без cv-квалификатора

>>
>> С чего бы он вдруг стал обязан? Компилятор обязан лишь обеспечить последовательное выполнение заданных действий в рамках одного потока исполнения. Для взаимодействия с "внешними" процессами и существует volatile.

ME>С тем, что состояние программы после sequence point is indeterminate.


Из чего это следует?

>> Простейший пример:

>>
>>
>> void f (int &a, int &b) {
>>   if (!a) {
>>     b = a;
>>   }
>> }
>>

>>
>> При включенной оптимизации многие компиляторы (например, VC++ 6.0) сгенерируют только один опрос переменной a — в проверке условия. Для присваивания будет сгенерирован явный нуль.

ME>Здесь именно простейший пример: нет вызовов ф-ций, компилятор видит весь контекст и плевал на sequence points. Добавим вызов ф-ции.


А давай вместо вызова функции добавим модификацию объекта — например, введем переменную c и сделаем ей инкремент:

  int c = b;

  if (!a) {

    c++;

    b = a;

  }

  return c;


Модификация объекта, согласно стандарту, есть sequence point. А по соглашениям MS любой оператор также является SP, и условие в if является ею же. Однако это не мешает компилятору по-прежнему использовать константу-нуль.

Я вообще не понимаю, почему ты относишь значение объекта к side effects.

ME>Мой point: volatile бесполезен (и даже вреден) для multithreading, барьеры нужны по-любому.


Где в C++ барьеры? Их там нет — они реализуются средствами платформы. Наличие барьеров без volatile не гарантирует правильной работы. Наличие volatile без барьеров — тоже не гарантирует. volatile обеспечивает поддержку со стороны языка, барьер — со стороны аппаратуры. Зачем, по-твоему, вообще существует volatile? Именно для урезания вольностей оптимизатора в отношении состояния объекта.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[4]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 10.01.05 18:51
Оценка:
c-smile wrote:

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

>
> ME>Наверное, LPLONG volatile* (star) Target? Почему же без volatile не получиться? Как и в функцию, которая принимает указатель на константный объект мы можем передать указатель на неконстнантный объект, но но не наооборот, так и в функциию принимающую указатель на волатильный, мы можем передать указатель на неволатильный объект.
>
> Нет именно так как я и написал. Это дословно из MSDN.

Sorry, это я ошибся, долбаные MS define'ы...

> ME>Вообще, квалификатор volatile у всех Interlocked* функций абсолютно бесполезен....

>
> Поверь мне (если не мне то хотя бы хедерам от WinSDK), очень полезен и стоит там по делу.
>
> Счастливый, ты еще не "втыкался" в проблемы связанные в hyperthreading по всей видимости.

Еще раз — volatile абсолютно бесполезен для multithreading.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[6]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 10.01.05 18:55
Оценка:
c-smile wrote:

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

>
>>> Прохождение sequence point отнюдь не гарантирует, что состояния всех объектов в этой точке будут непременно отражены в памяти — это гарантируется только для volatile-объектов.
>
> ME>Это не гарантируется большинством современных процессоров.
>
> Т.е. ты утверждаешь что в "большинстве современных процессоров" нет операции
> записи регистра в память? Или я не понял чего.

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

Ищи deja.com по ключевым словам "memory visibility"

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[2]: volatile у переменной класса
От: c-smile Канада http://terrainformatica.com
Дата: 10.01.05 19:02
Оценка: -2
Здравствуйте, MaximE, Вы писали:

ME>Рихтер ошибался.


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


Максим, я извиняюсь но вот эти твои высказывания неверны.

Для установки значения переменной в другом потоке используетс InterlockedExchange
На i386 это две инструкции lock и txchgl.

Mutexes (критические секции) для асинхронной установки значения это скажем так дурной тон. EnterCriticalSection/LeaveCriticalSection это два раза полновесный вызов Scheduler что не способствует быстродействию никак.
Re[6]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 10.01.05 19:07
Оценка:
emusic wrote:

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

>
> ME>Использование любого примитива синхронизации в POSIX и win32 является вызовом ф-ции. Вызов ф-ции — sequence point. Если у тебя уже есть sequence points вокруг защищаемых данных, зачем тогда volatile?
>
> Абсолютной необходимости в примитивах синхронизации нет. Если один процесс записывает значения в некоторую ячейку общей памяти, а другой их оттуда читает, и доступ к ячейке на всех поддерживаемых платформах гарантированно атомарный — какой смысл в дополнительных примитивах? Достаточно лишь указать компилятору, что с объектом нужно вести себя более аккуратно, что и делает volatile.

Атомарность и memory visibility ортогональны. См. мой предыдущий ответ.

[]

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

>
> ME>Это так только по случайному стечению обстоятельств на IA32.
>
> Почему по случайному? Еще не так давно подавляющее большинство платформ работало именно так.

Мы же работаем сегодня, а не вчера, верно?

> ME> volatile имеет влияние лишь на код, генерируемый компилятором. На переупорядочивание инструкций процессором он не имеет никакого влияния.

>
> А зачем? Назначение volatile — влиять именно на код. Соответственно, процессор своими средствами обеспечивает определенность вычислений.
>
> ME> Именно по этой причине на всех современных RISC процессорах, а также на IA64, тебе придется использовать барьеры памяти чтобы прочитать актуальное значение.
>
> Именно этим может и заниматься компилятор, обрабатывая volatile.

Ошибаешься. volatile не вставляет никаких барьеров. Барьеры обеспечиваются ф-циями http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/Synchro_88127404-a394-403f-a289-d61c45ab81d5.xml.asp

>>> ME> После sequence points, компилятор обязан перечитывать значения переменных из памяти, неважно, volatile ли, const ли, или это переменная без cv-квалификатора

>>>
>>> С чего бы он вдруг стал обязан? Компилятор обязан лишь обеспечить последовательное выполнение заданных действий в рамках одного потока исполнения. Для взаимодействия с "внешними" процессами и существует volatile.

volatile только для асинхронных обработчиков сигналов.

> ME>С тем, что состояние программы после sequence point is indeterminate.

>
> Из чего это следует?

Из стандарта С/С++.

[]

> А давай вместо вызова функции добавим модификацию объекта — например, введем переменную c и сделаем ей инкремент:

>
>
>   int c = b;
>
>   if (!a) {
>
>     c++;
>
>     b = a;
>
>   }
>
>   return c;
>

>
> Модификация объекта, согласно стандарту, есть sequence point. А по соглашениям MS любой оператор также является SP, и условие в if является ею же. Однако это не мешает компилятору по-прежнему использовать константу-нуль.

Вставь вызов ф-ции.

> ME>Мой point: volatile бесполезен (и даже вреден) для multithreading, барьеры нужны по-любому.

>
> Где в C++ барьеры?

В С++ их нет, в с++ нет multithreadind.

> Их там нет — они реализуются средствами платформы.


Это так.

> Наличие барьеров без volatile не гарантирует правильной работы. Наличие volatile без барьеров — тоже не гарантирует. volatile обеспечивает поддержку со стороны языка, барьер — со стороны аппаратуры.


Это ерунда. На POSIX все барьеры работают без volatile. POSIX работает практически на любой архитектуре. Почему это вдруг в vindoze на той же архитектуре понадобились volatile? Ответ один — от недопонимания.

> Зачем, по-твоему, вообще существует volatile? Именно для урезания вольностей оптимизатора в отношении состояния объекта.


volatile был введен в C и на сегодняшний день нужен только для асинхронных обработчиков сигналов. Точка.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[5]: volatile у переменной класса
От: c-smile Канада http://terrainformatica.com
Дата: 10.01.05 19:08
Оценка: 16 (2) :))
Здравствуйте, MaximE, Вы писали:

ME>Еще раз — volatile абсолютно бесполезен для multithreading.


"Зуб даешь?"
Re[3]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 10.01.05 19:11
Оценка:
c-smile wrote:

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

>
> ME>Рихтер ошибался.
>
> ME>volatile не имеет никакого отношения к multithreading, поэтому его применение в этой ситуации не только бесполезно, но может быть и вредно, так как с volatile компилятор не сможет соптимизировтать доступ к этой переменной. Но если один из потоков изменяет переменную, синхронизация при помощи мютексов обязательна.
>
> Максим, я извиняюсь но вот эти твои высказывания неверны.
>
> Для установки значения переменной в другом потоке используетс InterlockedExchange
> На i386 это две инструкции lock и txchgl.

Я говорил про volatile.

Никто не отрицает, что дешевле вызвать InterlockedExchange, чем pthread_mutex_acquire/EnterCriticalSection/etc...

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[6]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 10.01.05 19:12
Оценка: 14 (1) :)))
c-smile wrote:

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

>
> ME>Еще раз — volatile абсолютно бесполезен для multithreading.
>
> "Зуб даешь?"

mlja budu

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re: читаем про volatile
От: MaximE Великобритания  
Дата: 10.01.05 19:16
Оценка:
Вобщем, все вдумчиво читаем.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.