Re[6]: multithreading : visibility control
От: uzhas Ниоткуда  
Дата: 31.05.13 17:04
Оценка:
Здравствуйте, okman, Вы писали:

O>Это зависит от того, что именно находится в теле spawnThread.

там просто запуск потока, пусть будет beginthreadex

O>Например, там может быть установка булевого флага, в ожидании которого крутится другой поток.

нет там флагов, нет там ожидания, какие-то ненужные домыслы. в моем примере просто запускается второй поток и мне нужно аккуратно предоставить ему возможность увидеть консистентный и заполненный std::map

O>Вот почему в данном примере хардварные барьеры не нужны (на IA-32 и AMD64).

до сих пор не понял почему не нужен хардварный барьер. меня интересует общий случай для модели памяти, утвержденной в стандарт. Intel\AMD меня не интересуют в данном случае.

O>В результате на простом с виду коде имеем обе проблемы — видимость и переупорядочивание.

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

O>во-вторых, форсят обращение к памяти.

ну так вот это, видимо, и есть визибилити?!

O>В итоге получается два корректных варианта, один с volatile, второй с _ReadWriteBarrier.


O>unsigned int _stdcall Thread_Consumer(void *)

O>{
O> while (false == fReady)
O> {
O> _ReadWriteBarrier(); // Форсим обращение к памяти fReady.
O> }

O> if (1 != Value) throw;


O> return 0;

O>}

думаю, здесь форс получается не из-за _ReadWriteBarrier, давайте сюда вставим вызов любой другой сложной функции (пусть будет puts), думаю, поведение не изменится

O>Компилятор закэшировал один из членов std::queue в регистре и "не хочет" синхронизировать

O>его с реальным значением, хранящимся в памяти. Но стоит лишь добавить барьер компилятора,
O>как все становится на свои места:
аналогичная ситуация: компилятор просто боится того, что некая функция поменяет контейнер. поэтому не кеширует size() имхо

O>Остается вопрос: что выбрать — volatile или _ReadWriteBarrier ?

O>MSDN пишет:
O>http://msdn.microsoft.com/en-us/library/f20w0x5e(v=vs.100).aspx
O>

O>Marking memory with a memory barrier is similar to marking memory with the
O>volatile (C++) keyword. However, a memory barrier is more efficient because reads and
O>writes are forced to complete at specific points in the program rather than globally.
O>The optimizations that can occur if a memory barrier is used cannot occur if the
O>variable is declared volatile.


не очень понятно как поставить барьер именно на конкретную память. меня барьеры смущают именно из-за неконтролируемой гранулярности (отсутствие локального действия). volatile же привязывается к переменной — более локальное действие.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.