const volatile
От: Gregory Россия ICQ 300403361
Дата: 28.03.03 13:06
Оценка:
Господа! Объясните кто-нибудь, плз, как понимать const volatile и зачем оно такое нужно?
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re: const volatile
От: Павел Кузнецов  
Дата: 28.03.03 13:11
Оценка: 39 (6)
Здравствуйте, Gregory, Вы писали:

G>как понимать const volatile и зачем оно такое нужно?


volatile означает, что объект может изменяться как-то помимо действий программы, const — объект действиями программы через данный идентификатор не изменяется. const volatile — объект изменяется только "внешними" по отношению к программе способами. Например, данные какого-то внешнего устройства, отображенные на оперативную память.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: const volatile
От: Gregory Россия ICQ 300403361
Дата: 28.03.03 13:29
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

Исчерпывающе! Спасибо, Паша!
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re: const volatile
От: MaximE Великобритания  
Дата: 28.03.03 13:33
Оценка: 39 (4)
Здравствуйте, Gregory, Вы писали:

G>Господа! Объясните кто-нибудь, плз, как понимать const volatile и зачем оно такое нужно?


На тему volatile есть замечательная статейка Александреску: Generic<Programming>: volatile — Multithreaded Programmer’s Best Friend
const volatile
От: Кодт Россия  
Дата: 28.03.03 14:35
Оценка: 18 (7)
#Имя: FAQ.cpp.const_volatile
G>>как понимать const volatile и зачем оно такое нужно?

ПК>volatile означает, что объект может изменяться как-то помимо действий программы, const — объект действиями программы через данный идентификатор не изменяется. const volatile — объект изменяется только "внешними" по отношению к программе способами. Например, данные какого-то внешнего устройства, отображенные на оперативную память.


А также, и это наиболее важное применение: что объект может поменяться за пределами "прямой видимости":
— в другом потоке
— в какой-либо функции

Особенно это существенно для указателей и ссылок: могут одновременно существовать несколько разных способов доступиться до одного и того же предмета.

const — накладывает ограничение на модификацию "предмета" через данный идентификатор/ссылку/указатель,
volatile — сообщает компилятору, что нельзя кэшировать значение "предмета", т.к. он может неявно измениться в любой момент.
Перекуём баги на фичи!
Re[3]: const volatile
От: Saddam Россия http://saddam.narod.ru
Дата: 28.03.03 14:51
Оценка:
Здравствуйте, Кодт, Вы писали:

К>const — накладывает ограничение на модификацию "предмета" через данный идентификатор/ссылку/указатель,

К>volatile — сообщает компилятору, что нельзя кэшировать значение "предмета", т.к. он может неявно измениться в любой момент.
Кэшировать в данном случае — размещать в регистрах и всяких других местах, которые могут быть недоступны из других процессов, функций, и т.п.
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
Re[3]: const volatile
От: Аноним  
Дата: 28.03.03 14:59
Оценка:
Здравствуйте, Кодт, Вы писали:

К>А также, и это наиболее важное применение: что объект может поменяться за пределами "прямой видимости":

К>- в другом потоке
К>- в какой-либо функции

К>Особенно это существенно для указателей и ссылок: могут одновременно существовать несколько разных способов доступиться до одного и того же предмета.


Неправда ваша. Квалификация невозможности доступа по разным путям существует в Си и называется он restrict. В Си++ такой квалификации нет. А volatile к этому отношения не имеет.
Re[4]: const volatile
От: Кодт Россия  
Дата: 28.03.03 15:24
Оценка:
Здравствуйте, Аноним, Вы писали:

К>>Особенно это существенно для указателей и ссылок: могут одновременно существовать несколько разных способов доступиться до одного и того же предмета.


А>Неправда ваша. Квалификация невозможности доступа по разным путям существует в Си и называется он restrict. В Си++ такой квалификации нет. А volatile к этому отношения не имеет.


Видимо, мы друг друга недопоняли.

Несколько указателей на один и тот же предмет.
Один из них — указатель на константу.
Через другой — объект модифицируется.

Пример:
char global_buffer[100] = "world";

void effect()
{
  strcpy(global_buffer, "hello");
}

void view(const volatile char* text) // указывает на volatile данные
{
  if(text[0] != 'h') // *1*
    effect();

  ...

  if(text[0] != 'h') // *2*
    ...
}

int main()
{
  view("hi, it's literal");
  view(global_buffer);
}

Без volatile компилятор имеет право оптимизировать проверки *1*, *2*, например, запомнив результат в регистре, временной переменной, флаге состояния процессора... Что, естественно, приведет к некорректной работе.

Этот пример, конечно же, притянут за уши. Но в многопоточных приложениях — такое возможно с легкостью необычайной.
Перекуём баги на фичи!
Re[5]: const volatile
От: Аноним  
Дата: 28.03.03 15:35
Оценка: 15 (1)
Здравствуйте, Кодт, Вы писали:

А>>Неправда ваша. Квалификация невозможности доступа по разным путям существует в Си и называется он restrict. В Си++ такой квалификации нет. А volatile к этому отношения не имеет.


К>Видимо, мы друг друга недопоняли.


К>Несколько указателей на один и тот же предмет.

К>Один из них — указатель на константу.
К>Через другой — объект модифицируется.

К>Пример:

К>
К>char global_buffer[100] = "world";

К>void effect()
К>{
К>  strcpy(global_buffer, "hello");
К>}

К>void view(const volatile char* text) // указывает на volatile данные
К>{
К>  if(text[0] != 'h') // *1*
К>    effect();

К>  ...

К>  if(text[0] != 'h') // *2*
К>    ...
К>}

К>int main()
К>{
К>  view("hi, it's literal");
К>  view(global_buffer);
К>}
К>

К>Без volatile компилятор имеет право оптимизировать проверки *1*, *2*, например, запомнив результат в регистре, временной переменной, флаге состояния процессора... Что, естественно, приведет к некорректной работе.

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

В Си есть возможность квалификации restrict:

void view(const restrict char* text);


Вот в таком случае компилятор имеет законное право выполнять такую оптимизацию.

К>Этот пример, конечно же, притянут за уши.


Даже очень.

К>Но в многопоточных приложениях — такое возможно с легкостью необычайной.


Это иная история, приведенный вами пример к ней отношения не имеет; вот там — действительно царство volatile.
Re[6]: const volatile
От: _wqwa США  
Дата: 29.03.03 12:50
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Если он благородный (т. е. соответствующий стандарту) компилятор, он такого трюка не сделает. Компилятор не имеет возможности делать предположения об отсутствии иных ссылок, посредством коих значение text[0] может быть изменено по ходу исполнения программы.

Если мы говорим об одном потоке, то изменение данных через другую ссылку компилятор прелестно отследит и предварительно сбросит их из кеша. Поэтому кешировать данные ничто не мешает.
А если о нескольких -- тогда действительно volatile.
RSDN@Home
Кто здесь?!
Re[7]: const volatile
От: Аноним  
Дата: 29.03.03 15:03
Оценка:
Здравствуйте, _wqwa, Вы писали:

А>>Если он благородный (т. е. соответствующий стандарту) компилятор, он такого трюка не сделает. Компилятор не имеет возможности делать предположения об отсутствии иных ссылок, посредством коих значение text[0] может быть изменено по ходу исполнения программы.

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

Кэшировать, кэш, сбросить из кэша — это вы о чем вообще? О каком еще таком кэше? Который к тому же и компилятор сбрасывает?
Re[6]: const volatile
От: Диагностик Россия  
Дата: 31.03.03 03:09
Оценка:
Здравствуйте, Аноним, Вы писали:

К>>Без volatile компилятор имеет право оптимизировать проверки *1*, *2*, например, запомнив результат в регистре, временной переменной, флаге состояния процессора... Что, естественно, приведет к некорректной работе.


А>Если он благородный (т. е. соответствующий стандарту) компилятор, он такого трюка не сделает. Компилятор не имеет возможности делать предположения об отсутствии иных ссылок, посредством коих значение text[0] может быть изменено по ходу исполнения программы.


По-Вашему получается совершенно жуткая картина — запрещена практически любая оптимизация доступа к памяти вне стека.
И при оптимизации примера
if (*a == 0) *a += 2;

возможны два варианта:
1. если позволяет железо делаем все за один такт
2. в противном случае читаем по адресу a дважды — это же маразм, на фига нужна такая оптимизация?!

А если допустить такое извращение — поток №2 получил указатель на стек потока №1 (ну технически-то возможно ), то нужно запретить кэширование в регистрах даже стековых значений!!!
В чем же разница между volatile и не volatile в Вашей интерпретации?

Нигде ни читал подобного явным текстом, но всегда полагал существование у компилятора некой презумпции однопоточности — предполагается что значение может быть изменено только из текущего потока, если не указано обратное — volatile. Разве это не так?
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[7]: const volatile
От: Павел Кузнецов  
Дата: 31.03.03 06:28
Оценка:
Здравствуйте, Диагностик, Вы писали:

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

Д> предполагается что значение может быть изменено только из текущего
Д> потока, если не указано обратное — volatile. Разве это не так?

Зависит от конкретной реализации, но в общем именно так и есть.
Posted via RSDN NNTP Server 1.4.6 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[8]: const volatile
От: Кодт Россия  
Дата: 31.03.03 08:10
Оценка: 8 (1)
Здравствуйте, Аноним, Вы писали:

А>Кэшировать, кэш, сбросить из кэша — это вы о чем вообще? О каком еще таком кэше? Который к тому же и компилятор сбрасывает?


Значения переменных, результаты вычисления выражений — записываются в различные временные переменные (физически расположенные как в регистрах процессора, так и в памяти).
Отчасти это обусловлено архитектурой процессоров, отчасти — соображениями оптимизации.

Эти временные переменные и зовут в данном случае кэшем.

Так вот, у временных переменных есть "срок годности", т.е. текущее значение совпадает с правильным некоторое время.

Например, содержимое регистра EAX не меняется до перезаписи и до вызова функции (точнее, там его значение не гарантируется).
Поэтому
int *x, y, z;
...
y = x[0] * 2;
z = x[0] * 3;
printf("hello");
t = x[0] * 4;

можно оптимизировать, считав значение x[0] в EAX и затем использовать его в вычислении y, z. После выполнения printf значение EAX станет другим, поэтому t потребует новой загрузки x[0].
Но компилятор может объехать эту проблему, загрузив x[0] во временную переменную x0, размещенную на стеке.

Кэш "портится" не только сам по себе, но и потому, что исходные данные изменились.
Если компилятор может это отследить, например,
y = x[0] * 2;
x[0]++; // изменилось значение по тому же адресу
z = x[0] * 3;
x++; // изменился сам адрес
t = x[0] * 4;

то кэш будет "сброшен".

Но, как уже говорилось выше, значение могут поменять "со стороны". В таком случае переменную объявляют volatile.
Перекуём баги на фичи!
Re[9]: const volatile
От: Аноним  
Дата: 31.03.03 08:22
Оценка: -2
Здравствуйте, Кодт:

Я просто-таки удивлен этаким вашим "разъяснением". Все, надеюсь, и так отлично знают, как устроен процессор. Все в курсе, что у процессора есть регистры. Однако регистры — это не кэш! У данных в регистрах нет "срока годности". Компилятор "сбрасыванием" кэша не занимается.

Компилятор может генерировать код, который выполняет действия над повторно употребляемыми объектами в регистрах. Но это не кэширование по своей сути.
Re[10]: const volatile
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 31.03.03 08:36
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Я просто-таки удивлен этаким вашим "разъяснением". Все, надеюсь, и так отлично знают, как устроен процессор. Все в курсе, что у процессора есть регистры. Однако регистры — это не кэш! У данных в регистрах нет "срока годности". Компилятор "сбрасыванием" кэша не занимается.


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

А>Компилятор может генерировать код, который выполняет действия над повторно употребляемыми объектами в регистрах. Но это не кэширование по своей сути.


Назови это, как считаешь правильным. И напиши здесь свое объяснение на тему volatile. Это будет интереснее, чем читать бесконструктивные придирки.

Без обид
... << RSDN@Home 1.0 beta 6a >>
Re[10]: const volatile
От: Кодт Россия  
Дата: 31.03.03 08:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Я просто-таки удивлен этаким вашим "разъяснением". Все, надеюсь, и так отлично знают, как устроен процессор. Все в курсе, что у процессора есть регистры. Однако регистры — это не кэш! У данных в регистрах нет "срока годности". Компилятор "сбрасыванием" кэша не занимается.


Не путайте аппаратный кэш процессора и временные переменные, используемые программой (порожденной компилятором).
Например, регистр AX|EAX, интенсивно используемый в процессорах x86 — это именно кэш, поскольку в оригинальной программе на Си о нем не упоминается.

А>Компилятор может генерировать код, который выполняет действия над повторно употребляемыми объектами в регистрах. Но это не кэширование по своей сути.


Именно кэширование по своей сути (хранение значений в памяти с быстрым доступом).
И необязательно в регистры процессора, но также в память на стеке и TLS.
Перекуём баги на фичи!
Re[11]: const volatile
От: Аноним  
Дата: 31.03.03 09:04
Оценка:
Здравствуйте, Михаил Можаев, Вы писали:

ММ>Назови это, как считаешь правильным. И напиши здесь свое объяснение на тему volatile. Это будет интереснее, чем читать бесконструктивные придирки.


volatile мы уже проехали, вопрос в том, что употребление слова "кэш" здесь неверно и может вводить в заблуждение относительно того, как это все работает.
Re[11]: const volatile
От: Аноним  
Дата: 31.03.03 09:12
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Именно кэширование по своей сути (хранение значений в памяти с быстрым доступом).

К>И необязательно в регистры процессора, но также в память на стеке и TLS.

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

Пассаж про данные на стеке и в TLS вообще не ясен (особенно учитывая скорость доступа в TLS).
Re[7]: const volatile
От: Аноним  
Дата: 31.03.03 09:17
Оценка:
Здравствуйте, Диагностик, Вы писали:

Д>По-Вашему получается совершенно жуткая картина — запрещена практически любая оптимизация доступа к памяти вне стека.


Нет, отчего же.

Д>И при оптимизации примера

Д>
Д>if (*a == 0) *a += 2;
Д>

Д>возможны два варианта:
Д>1. если позволяет железо делаем все за один такт
Д>2. в противном случае читаем по адресу a дважды — это же маразм, на фига нужна такая оптимизация?!

Этот пример отличается от предыдущего, по ходу выполнения в нем нет между двумя ссылками на *a других ссылок, потенциально могущих вести к тому же объекту, что и *a. Здесь оптимизация возможна.

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


В общем, так; разъяснение выше дано именно исходя из этого.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.