Re[7]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 14.07.10 22:45
Оценка: 7 (5) +1
Здравствуйте, tripol, Вы писали:

T>Банально все сводится к использованию CriticalSection или Mutex-ов без каких-либо забот

T>об кэшах.

Банально — это InterlockedExchange и иже с ней, если мы про Windows. Критические секции и мьютексы, в данном случае — из пушки по воробьям.
Re[11]: вопрос по синхронизации в многопоточной среде
От: night beast СССР  
Дата: 16.07.10 05:05
Оценка: 8 (1)
Здравствуйте, uzhas, Вы писали:

__>>>
__>>>x ^= (y ^= (x ^= y));
__>>>



Q>>А это вообще Undefined Behavior.

U>пояснить можете, где тут UB ? какой пункт стандарта нарушается?
U>о каких типах переменных речь? int, unsigned ?

дык эта, модифицирование одной переменной несколько раз между точками следования.
бородатый пример.
Re: вопрос по синхронизации в многопоточной среде
От: Sni4ok  
Дата: 14.07.10 16:00
Оценка: 2 (1)
Здравствуйте, sidorov18, Вы писали:

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


а что в данном случае не воспользоваться interlocked функциями?
Re[16]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 16.07.10 07:42
Оценка: 2 (1)
Здравствуйте, sidorov18, Вы писали:

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


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


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

S>>>зы. класс — COM класс, компилятор ничего не заинлайнит.

T>>Если COM, то можно обойтись.

T>>Кроме прочего для понятности volatile можно использовать, что бы помечать,
T>>что данная переменная или функция может быть безопасно использоваться
T>>другими потоками.

S>а в случае с 8-и байтовой переменнной? тоже можно использовать без volatile?


Если 64-битный код, то да (необходимо выравнивание по 64 битам).

Если 32-битный:
Под XP и выше — использовать CriticalSection (выравнивание не требуется)

InterlockedExchange64 и InterlockedExchange64 то же требуют
выравнивания и работают начиная с Windows Server 2003 и Windows Vista.
Re[5]: вопрос по синхронизации в многопоточной среде
От: quodum  
Дата: 16.07.10 11:32
Оценка: 2 (1)
Здравствуйте, sidorov18, Вы писали:

Q>>На многопроцессорной системе может не успеть никогда (пока из локального кэша старое значение не вытеснится).

S>а можо в двух словах что такое локальный кеш? т.е. копия переменной в памяти хранится еще где-то, кроме памяти?

Да, в дополительной быстрой памяти на самом процессоре. См. здесь
Re[6]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 10:29
Оценка: 1 (1)
Здравствуйте, MasterZiv, Вы писали:

MZ>tripol wrote:


>> А что, по твоему, процессор записывает в память / кэш по половине DWORD?


MZ>С уверенностью можно сказать только одно: меньше чем байт в память не

MZ>записать и не считать из неё. А вот остальное ...

По умолчанию компилятор выравнивает DWORD-ы как минимум по границе в 4 байта,
а операции чтения/записи с таких адресов являются атомарными.
Re[7]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 10:41
Оценка: 1 (1)
Здравствуйте, tripol, Вы писали:

T>По умолчанию компилятор выравнивает DWORD-ы как минимум по границе в 4 байта,

T>а операции чтения/записи с таких адресов являются атомарными.

Дабы закончить свое участие в этой дискуссии, процитирую интеловскую матчасть:

8.1.1 Guaranteed Atomic Operations
The Intel486 processor (and newer processors since) guarantees that the following
basic memory operations will always be carried out atomically:
• Reading or writing a byte
• Reading or writing a word aligned on a 16-bit boundary
• Reading or writing a doubleword aligned on a 32-bit boundary
The Pentium processor (and newer processors since) guarantees that the following
additional memory operations will always be carried out atomically:
• Reading or writing a quadword aligned on a 64-bit boundary
• 16-bit accesses to uncached memory locations that fit within a 32-bit data bus
The P6 family processors (and newer processors since) guarantee that the following
additional memory operation will always be carried out atomically:
• Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache
line
Accesses to cacheable memory that are split across cache lines and page boundaries
are not guaranteed to be atomic by the Intel Core 2 Duo, Intel® Atom™, Intel Core
Duo, Pentium M, Pentium 4, Intel Xeon, P6 family, Pentium, and Intel486 processors.
The Intel Core 2 Duo, Intel Atom, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon,
and P6 family processors provide bus control signals that permit external memory
subsystems to make split accesses atomic; however, nonaligned data accesses will
seriously impact the performance of the processor and should be avoided.

bloß it hudla
Re[8]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 14.07.10 22:51
Оценка: -1
Здравствуйте, tripol, Вы писали:

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


T>И в случае с вопросом топик-стартера можно использовать приведенный класс,

T>но только необходимо добавить volatile.

Отключение агрессивной оптимизации тут вряд ли поможет — нечего оптимизировать
Re[3]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 07:55
Оценка: -1
Здравствуйте, sidorov18, Вы писали:

S>Какой угодно, где стоит винда)


Тогда никаких расслоений значения при чтении/записи из разных нитей не будет, можно не бояться.
bloß it hudla
вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 14.07.10 14:43
Оценка:
есть класс:
class A
{
   long m_a;
public:
   long get_a()
   {
      return m_a;
   }
   void set_a( long val )
   {
      m_a = val;
   }
}

методы get_a и set_a вызываются из разных потоков.

вопрос:
может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде:
старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?
Re: вопрос по синхронизации в многопоточной среде
От: uzhas Ниоткуда  
Дата: 14.07.10 15:00
Оценка:
Здравствуйте, sidorov18, Вы писали:

S>вопрос:

S>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде:
S>старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?

может
Re[2]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 14.07.10 15:19
Оценка:
Здравствуйте, uzhas, Вы писали:

U>может


Интересно как, ведь операции процессора являются дискретными, а в данном случае я полагаю
используется 32-битный код, следовательно чтение или запись производится одной
операцией и следовательно половинное значение получить невозможно.
Re: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 14.07.10 15:22
Оценка:
Здравствуйте, sidorov18, Вы писали:

S>вопрос:

S>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде:
S>старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?

Процессор какой?
bloß it hudla
Re[3]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 14.07.10 15:47
Оценка:
Здравствуйте, tripol, Вы писали:

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


U>>может


T>Интересно как, ведь операции процессора являются дискретными, а в данном случае я полагаю

T>используется 32-битный код, следовательно чтение или запись производится одной
T>операцией и следовательно половинное значение получить невозможно.

Ну, во-первых, 32хбитный код не обязательно подразумевает 32хразрядную шину данных. Во-вторых, чтение и запись запросто могут быть не в память, а в кеш. И тут вообще может случиться много забавного. Например, первые два байта в одной строке, остальные — в другой.
Re[4]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 14.07.10 16:08
Оценка:
Здравствуйте, _stun_, Вы писали:

__>Ну, во-первых, 32хбитный код не обязательно подразумевает 32хразрядную шину данных. Во-вторых, чтение и запись запросто могут быть не в память, а в кеш. И тут вообще может случиться много забавного. Например, первые два байта в одной строке, остальные — в другой.


Для программы кэш должен быть прозрачным, иначе тогда много геморою...
Re[5]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 14.07.10 16:23
Оценка:
Здравствуйте, tripol, Вы писали:


T>Для программы кэш должен быть прозрачным, иначе тогда много геморою...


Должен — это когда взял, и не отдал Разговор идет про то, что есть, а не про то, что могло бы быть.
Re[6]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 14.07.10 16:53
Оценка:
Здравствуйте, _stun_, Вы писали:

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



T>>Для программы кэш должен быть прозрачным, иначе тогда много геморою...


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


Если в системе есть подобные неоднозначности — то тут тогда необходимо выполнять синхронизацию
кэшей программно. Но хорошо, что разработчики систем от этого гемороя програмистов берегут.
Смотрите: MSEI Protocol

Банально все сводится к использованию CriticalSection или Mutex-ов без каких-либо забот
об кэшах.
Re[7]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 14.07.10 16:58
Оценка:
Здравствуйте, tripol, Вы писали:

И в случае с вопросом топик-стартера можно использовать приведенный класс,
но только необходимо добавить volatile.
Re: вопрос по синхронизации в многопоточной среде
От: okman Беларусь https://searchinform.ru/
Дата: 14.07.10 17:17
Оценка:
Здравствуйте, sidorov18, Вы писали:

S>есть класс:

S>
S>class A
S>{
S>   long m_a;
S>public:
S>   long get_a()
S>   {
S>      return m_a;
S>   }
S>   void set_a( long val )
S>   {
S>      m_a = val;
S>   }
S>}
S>

S>методы get_a и set_a вызываются из разных потоков.

S>вопрос:

S>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде:
S>старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?

Такое может случиться на многопроцессорных системах, или если член данных m_a не выровнен по
границе машинного слова, "родного" для архитектуры, на которой запускается программа.
Советую не искушать судьбу и использовать CRITICAL_SECTION.
Re: вопрос по синхронизации в многопоточной среде
От: savitar  
Дата: 14.07.10 18:21
Оценка:
Здравствуйте, sidorov18, Вы писали:

S>...

интересно, а предыдущее значение устраивает?
Re[2]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 15.07.10 07:16
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

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


S>>вопрос:

S>>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде:
S>>старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?

AL>Процессор какой?


Какой угодно, где стоит винда)
Re[2]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 15.07.10 07:18
Оценка:
Здравствуйте, savitar, Вы писали:

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


S>>...

S>интересно, а предыдущее значение устраивает?
да. раз не успел... то ладно)
Re[8]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 15.07.10 07:21
Оценка:
Здравствуйте, _stun_, Вы писали:

__>Банально — это InterlockedExchange и иже с ней, если мы про Windows. Критические секции и мьютексы, в данном случае — из пушки по воробьям.



Спасибо. Я так понимаю, Критические секции и мьютексы работают медленнее, чем Interlocked ф-ии?
И еще. тут предложили использовать volatile.. поможет ли volatile? компилятор — vs2005.
Re[4]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 15.07.10 07:23
Оценка:
Здравствуйте, _stun_, Вы писали:

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


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


U>>>может


T>>Интересно как, ведь операции процессора являются дискретными, а в данном случае я полагаю

T>>используется 32-битный код, следовательно чтение или запись производится одной
T>>операцией и следовательно половинное значение получить невозможно.

__>Ну, во-первых, 32хбитный код не обязательно подразумевает 32хразрядную шину данных. Во-вторых, чтение и запись запросто могут быть не в память, а в кеш. И тут вообще может случиться много забавного. Например, первые два байта в одной строке, остальные — в другой.


А скажите пожалуйста, что за кеш?
Re[9]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 07:43
Оценка:
Здравствуйте, _stun_, Вы писали:

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


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


T>>И в случае с вопросом топик-стартера можно использовать приведенный класс,

T>>но только необходимо добавить volatile.

__>Отключение агрессивной оптимизации тут вряд ли поможет — нечего оптимизировать


Вполне может прооптимизировать такой код:


class A{
   long m_a;
public:
   long get_a()
   {
      return m_a;
   }
   void set_a( long val )
   {
      m_a = val;
   }
};

A a;

void Thread1()
{
    a.set_a(1);
}

int main()
{
    a.set_a(0);
    // start new thread to Thread1()
    while(!a.get_a()) // здесь может заинлайнить и без volatile цикл не выйдет
    {
    }
}


И вообще рекомендуется применять volatile для таких случаев всегда независимо от того,
заоптимизирует данный компилятор или нет.
Re[3]: вопрос по синхронизации в многопоточной среде
От: MasterZiv СССР  
Дата: 15.07.10 08:01
Оценка:
tripol wrote:

> Интересно как, ведь операции процессора являются дискретными, а в данном

> случае я полагаю
> используется 32-битный код, следовательно чтение или запись производится
> одной

Кто тебе сказал, что операции процессора являются дискретными ?
Posted via RSDN NNTP Server 2.1 beta
Re[4]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 08:33
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>tripol wrote:


>> Интересно как, ведь операции процессора являются дискретными, а в данном

>> случае я полагаю
>> используется 32-битный код, следовательно чтение или запись производится
>> одной

MZ>Кто тебе сказал, что операции процессора являются дискретными ?


А что, по твоему, процессор записывает в память / кэш по половине DWORD?
Re[4]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 08:47
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

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


S>>Какой угодно, где стоит винда)


AL>Тогда никаких расслоений значения при чтении/записи из разных нитей не будет, можно не бояться.


Неправда Ваша. На старых процах случалось, потому interlocked-функции и появились. И никакой гарантии, что на будущих проблема опять не выплывет.
Re[5]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 08:51
Оценка:
__>Неправда Ваша. На старых процах случалось, потому interlocked-функции и появились. И никакой гарантии, что на будущих проблема опять не выплывет.

Гарантия есть — обратная совместимость.
Re[5]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 08:55
Оценка:
Здравствуйте, _stun_, Вы писали:

__>Неправда Ваша. На старых процах случалось, потому interlocked-функции и появились. И никакой гарантии, что на будущих проблема опять не выплывет.


На каких именно процах, где может функционировать Windows, команда пересылки между 32-разрядным регистром и памятью не была атомарной?
bloß it hudla
Re[5]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 09:02
Оценка:
Здравствуйте, _stun_, Вы писали:

__>Неправда Ваша. На старых процах случалось, потому interlocked-функции и появились. И никакой гарантии, что на будущих проблема опять не выплывет.


interlocked-инструкции и функции появились для реализации высокоуровневых атомарных операций, которые нельзя реализовать одной существующей инструкцией (например, CAS, инкремент и пр.).
bloß it hudla
Re[9]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 09:04
Оценка:
Здравствуйте, sidorov18, Вы писали:

S>Спасибо. Я так понимаю, Критические секции и мьютексы работают медленнее, чем Interlocked ф-ии?


Мьютексы — однозначно медленнее. Критические секции — как повезет, но однозначно не быстрее. Ну и основное и единственное назначение Interlocked-функций — обеспечивать атомарность операции доступа. Не стоит еще какой-нибудь велосипед изобретать.

S>И еще. тут предложили использовать volatile.. поможет ли volatile? компилятор — vs2005.


В данном случае — ничем, как и остальные средства языка. В следующем стандарте обещают ситуацию исправить.
Re[6]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 09:13
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>На каких именно процах, где может функционировать Windows, команда пересылки между 32-разрядным регистром и памятью не была атомарной?


Сам лично сталкивался на двухпроцессорной четверке. Зависит, кстати, не столько от процессора, сколько от контроллера кеша.
Re[6]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 09:15
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>interlocked-инструкции и функции появились для реализации высокоуровневых атомарных операций, которые нельзя реализовать одной существующей инструкцией (например, CAS, инкремент и пр.).


И эта тоже?
Re[10]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 09:16
Оценка:
Здравствуйте, _stun_, Вы писали:

S>>И еще. тут предложили использовать volatile.. поможет ли volatile? компилятор — vs2005.


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


В данном случае как раз поможет, и без всяких Interlocked-функций. InterlockedExchange — функция использующаяся
для записи, а что ты предлагаешь использовать для чтения переменной, и тем более без volatile?
Не вводи в заблуждение.

InterlockedExchange генерирует memory barrier, который гарантирует последовательность выполнения операций
с памятью, и в данном случае это не требуется.
Re[11]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 09:19
Оценка:
Ну тоесть InterlockedExchange — функция использующаяся и для чтения, но volatile необходимо,
кстати оно присутствует в объявлении функции
LONG __cdecl InterlockedExchange(
__in_out LONG volatile* Target,
__in LONG Value
);
Re[7]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 09:21
Оценка:
Здравствуйте, _stun_, Вы писали:

__>Здравствуйте, A.Lokotkov, Вы писали:


AL>>interlocked-инструкции и функции появились для реализации высокоуровневых атомарных операций, которые нельзя реализовать одной существующей инструкцией (например, CAS, инкремент и пр.).


__>И эта тоже?


Ну насколько я знаю команды процессора такой нет.
Re[7]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 09:24
Оценка:
Здравствуйте, _stun_, Вы писали:

__>Здравствуйте, A.Lokotkov, Вы писали:


AL>>interlocked-инструкции и функции появились для реализации высокоуровневых атомарных операций, которые нельзя реализовать одной существующей инструкцией (например, CAS, инкремент и пр.).


__>И эта тоже?


Конечно да, поскольку невозможно объяснить компилятору языка высокого уровня, что программист желает атомарно обменять содержимое двух ячеек памяти либо вернуть старое значение, заменив его на константу.
bloß it hudla
Re[8]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 09:28
Оценка:
Здравствуйте, tripol, Вы писали:

__>>И эта тоже?


T>Ну насколько я знаю команды процессора такой нет.


Атомарно вернуть старое значение, заменив его константой, на x86 можно при помощи древней xchg.
bloß it hudla
Re[10]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 09:35
Оценка:
Здравствуйте, tripol, Вы писали:

T>Вполне может прооптимизировать такой код:



T>
T>    while(!a.get_a()) // здесь может заинлайнить и без volatile цикл не выйдет
T>


Согласен, хотя к проблеме, поднятой топикстартером, это мало относится. И, кстати, InterlockedExchange заодно уж и эту опасность устранит.

T>И вообще рекомендуется применять volatile для таких случаев всегда независимо от того,

T>заоптимизирует данный компилятор или нет.

Ну, это смотря что считать "таким случаем". Можно и производительность нафиг загробить. Если в общем рассуждать, лучше доступ ко всему объекту из разных потоков грамотно организовывать, а не на уровне отдельных членов.
Re[8]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 09:47
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>Конечно да, поскольку невозможно объяснить компилятору языка высокого уровня, что программист желает атомарно обменять содержимое двух ячеек памяти либо вернуть старое значение, заменив его на константу.



x ^= (y ^= (x ^= y));
Re[12]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 09:53
Оценка:
Здравствуйте, tripol, Вы писали:

T>Ну тоесть InterlockedExchange — функция использующаяся и для чтения, но volatile необходимо,

T>кстати оно присутствует в объявлении функции
T>LONG __cdecl InterlockedExchange(
T> __in_out LONG volatile* Target,
T> __in LONG Value
T>);

Вот теперь согласен
Re[11]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 09:57
Оценка:
__>Согласен, хотя к проблеме, поднятой топикстартером, это мало относится. И, кстати, InterlockedExchange заодно уж и эту опасность устранит.

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

T>>И вообще рекомендуется применять volatile для таких случаев всегда независимо от того,

T>>заоптимизирует данный компилятор или нет.

__>Ну, это смотря что считать "таким случаем". Можно и производительность нафиг загробить. Если в общем рассуждать, лучше доступ ко всему объекту из разных потоков грамотно организовывать, а не на уровне отдельных членов.


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

А спецификатор volatile исключает вышеприведенную зацикленность и другие подобные возможные случаи.
Re[9]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 10:01
Оценка:
Здравствуйте, _stun_, Вы писали:

__>
__>x ^= (y ^= (x ^= y));
__>


Здесь будет сгенерировано около шести пересылок между памятью и регистрами. Про то, что все это должно произойти атомарно, здесь не написано.
bloß it hudla
Re[5]: вопрос по синхронизации в многопоточной среде
От: MasterZiv СССР  
Дата: 15.07.10 10:03
Оценка:
tripol wrote:

> А что, по твоему, процессор записывает в память / кэш по половине DWORD?


С уверенностью можно сказать только одно: меньше чем байт в память не
записать и не считать из неё. А вот остальное ...
Posted via RSDN NNTP Server 2.1 beta
Re[7]: вопрос по синхронизации в многопоточной среде
От: uzhas Ниоткуда  
Дата: 15.07.10 10:42
Оценка:
Здравствуйте, tripol, Вы писали:

T>По умолчанию компилятор выравнивает DWORD-ы как минимум по границе в 4 байта,

T>а операции чтения/записи с таких адресов являются атомарными.
это верно не для всех платформ, для x86 верно
Re[12]: вопрос по синхронизации в многопоточной среде
От: uzhas Ниоткуда  
Дата: 15.07.10 10:46
Оценка:
Здравствуйте, tripol, Вы писали:

T>Ну тоесть InterlockedExchange — функция использующаяся и для чтения, но volatile необходимо,

T>кстати оно присутствует в объявлении функции
T>LONG __cdecl InterlockedExchange(

есть мнение, что наличие volatile говорит лишь о том, что данная функция в том числе может работать с volatile переменной, ибо навесить volatile легко, а снять тяжело
Re[13]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 11:06
Оценка:
Здравствуйте, uzhas, Вы писали:

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


T>>Ну тоесть InterlockedExchange — функция использующаяся и для чтения, но volatile необходимо,

T>>кстати оно присутствует в объявлении функции
T>>LONG __cdecl InterlockedExchange(

U>есть мнение, что наличие volatile говорит лишь о том, что данная функция в том числе может работать с volatile переменной, ибо навесить volatile легко, а снять тяжело


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

Кроме того доступ к volatile переменной быстрее чем использование InterlockedExchange,
и поэтому тем более не вижу каких либо проблем для использования volatile.
Re[13]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 11:10
Оценка:
Здравствуйте, uzhas, Вы писали:

U>есть мнение, что наличие volatile говорит лишь о том, что данная функция в том числе может работать с volatile переменной, ибо навесить volatile легко, а снять тяжело


Вообще то функция воспринимает эту переменную как volatile (не volatile приводится к volatile).
Re[11]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 15.07.10 11:27
Оценка:
Здравствуйте, tripol, Вы писали:

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


S>>>И еще. тут предложили использовать volatile.. поможет ли volatile? компилятор — vs2005.


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


T>В данном случае как раз поможет, и без всяких Interlocked-функций. InterlockedExchange — функция использующаяся

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

T>InterlockedExchange генерирует memory barrier, который гарантирует последовательность выполнения операций

T>с памятью, и в данном случае это не требуется.

так всетаки неясно насчет volatile...
volatile в msdn
в мсдн написано, что при каждой обращении будет считано текущее значение volatile переменной(из памяти имеется ввиду, да?). А далее говорится, что-то про Microsoft specific..там говорится о каких-то aquire и release semantics.. и что они означают я пока не понял... объясните кто-то пожалуйста)
вот тут некая Алена С++ пишет, что это говорит о атомарности операций с переменной.
Если это так... то это вроде то, что нужно.
Вообще значение переменной меняется из одного потока, а вот считывается многими.. и если volatile действительно дает атомарность.. значит *Interlocked ф-ями можно не пользоваться. так?
Re[12]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 11:48
Оценка:
Здравствуйте, sidorov18, Вы писали:

S>так всетаки неясно насчет volatile...

S>volatile в msdn
S>в мсдн написано, что при каждой обращении будет считано текущее значение volatile переменной(из памяти имеется ввиду, да?). А далее говорится, что-то про Microsoft specific..там говорится о каких-то aquire и release semantics.. и что они означают я пока не понял... объясните кто-то пожалуйста)
S>вот тут некая Алена С++ пишет, что это говорит о атомарности операций с переменной.
S>Если это так... то это вроде то, что нужно.
S>Вообще значение переменной меняется из одного потока, а вот считывается многими.. и если volatile действительно дает атомарность.. значит *Interlocked ф-ями можно не пользоваться. так?

Тут важно знать следующее:
* как уже было написано, атомарность чтения/записи в память на большинстве 32-бит, 64-битных архитектур(IA32, x64 в их числе) гарантируется,
если DWORD выровнен по 4-байтной сетке и выше. (это по умолчанию если не крутить соответствующие настройки проекта).
* volatile необходимо для того, что бы указать компилятору, что необходимо генерировать такой код, который
будет брать/записывать каждый раз значение из памяти, а не как иначе.

Тоесть тут два уровня: уровень компилятора(откомпилированного кода) и уровень процессора и памяти.
Re[9]: вопрос по синхронизации в многопоточной среде
От: quodum  
Дата: 15.07.10 14:04
Оценка:
Здравствуйте, _stun_, Вы писали:

__>
__>x ^= (y ^= (x ^= y));
__>



А это вообще Undefined Behavior.
Re[3]: вопрос по синхронизации в многопоточной среде
От: quodum  
Дата: 15.07.10 14:06
Оценка:
Здравствуйте, sidorov18, Вы писали:

S>>интересно, а предыдущее значение устраивает?

S>да. раз не успел... то ладно)

На многопроцессорной системе может не успеть никогда (пока из локального кэша старое значение не вытеснится).
Re[10]: вопрос по синхронизации в многопоточной среде
От: uzhas Ниоткуда  
Дата: 15.07.10 15:14
Оценка:
Здравствуйте, quodum, Вы писали:

__>>
__>>x ^= (y ^= (x ^= y));
__>>



Q>А это вообще Undefined Behavior.

пояснить можете, где тут UB ? какой пункт стандарта нарушается?
о каких типах переменных речь? int, unsigned ?
Re[8]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 17:02
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

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


T>>По умолчанию компилятор выравнивает DWORD-ы как минимум по границе в 4 байта,

T>>а операции чтения/записи с таких адресов являются атомарными.

По умолчанию — это далеко не всегда.

AL>Дабы закончить свое участие в этой дискуссии, процитирую интеловскую матчасть:


Спасибо за цитату, весь день собирался, но ленился сам искать. Короче, под win вполне может беда случиться
Re[12]: вопрос по синхронизации в многопоточной среде
От: _stun_ Россия  
Дата: 15.07.10 17:12
Оценка:
Здравствуйте, tripol, Вы писали:

__>>Согласен, хотя к проблеме, поднятой топикстартером, это мало относится. И, кстати, InterlockedExchange заодно уж и эту опасность устранит.


T>Не вижу смысла каждый раз читать + писать в память тогда когда достаточно просто читать или просто писать.


То, что InterlockedExchange возвращает значение — приятный это побочный результат эффективной реализации этой функции, а не основное ее назначение.

T>Производительность как раз можно загробить там где без необходимости используются memory barriers и лишние

T>записи / чтения.

T>А спецификатор volatile исключает вышеприведенную зацикленность и другие подобные возможные случаи.


volatile вполне себе может привести как раз к лишним записям/чтениям, он для этого и предназначен. Но у нас разговор уже по кругу пошел.
Re[9]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 17:34
Оценка:
Здравствуйте, _stun_, Вы писали:

__>Спасибо за цитату, весь день собирался, но ленился сам искать. Короче, под win вполне может беда случиться


И все таки, как просто считать значение переменной, если она вдруг не выровнена.

Тут InterlockedExchange не поможет, поскольку изменяет значение...
Re[13]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 17:41
Оценка:
Здравствуйте, _stun_, Вы писали:

__>То, что InterlockedExchange возвращает значение — приятный это побочный результат эффективной реализации этой функции, а не основное ее назначение.


Это основное ее назначение, поскольку функция называется не InterlockedWrite.

__>volatile вполне себе может привести как раз к лишним записям/чтениям, он для этого и предназначен.


Нет при операции чтения — это чтение, а при операции записи — это запись, а не все вместе.
Re[10]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 18:26
Оценка:
Здравствуйте, tripol, Вы писали:

T>И все таки, как просто считать значение переменной, если она вдруг не выровнена.

T>Тут InterlockedExchange не поможет, поскольку изменяет значение...

Она может быть не выровнена, если компилятору задали явно кривое выравнивание, например, на 1 или 2 (в 2008-й студии по умолчанию 8). Вероятно, поможет InterlockedExchangeAdd с нулем в качестве второго аргумента. "Вероятно", поскольку в Windows CE, которая тоже какбэ винда, первый аргумент должен смотреть на выровненную переменную.
bloß it hudla
Re[11]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 18:33
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

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


T>>И все таки, как просто считать значение переменной, если она вдруг не выровнена.

T>>Тут InterlockedExchange не поможет, поскольку изменяет значение...

AL>Она может быть не выровнена, если компилятору задали явно кривое выравнивание, например, на 1 или 2 (в 2008-й студии по умолчанию 8). Вероятно, поможет InterlockedExchangeAdd с нулем в качестве второго аргумента. "Вероятно", поскольку в Windows CE, которая тоже какбэ винда, первый аргумент должен смотреть на выровненную переменную.



Цитата из MSDN:
"Remarks
...
The variables for this function must be aligned on a 32-bit boundary; otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems.
..."
Re[12]: вопрос по синхронизации в многопоточной среде
От: A.Lokotkov Россия  
Дата: 15.07.10 18:56
Оценка:
Здравствуйте, tripol, Вы писали:

T>Цитата из MSDN:

T>"Remarks
T>...
T>The variables for this function must be aligned on a 32-bit boundary; otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems.
T>..."

Ага, значит, я ошибся -- в большой венде тоже нельзя. Кстати, для чего может потребоваться кривое выравнивание в кошерной программе? Сериализация/десериализация в индусском стиле?
bloß it hudla
Re[13]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 19:30
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>Ага, значит, я ошибся -- в большой венде тоже нельзя. Кстати, для чего может потребоваться кривое выравнивание в кошерной программе? Сериализация/десериализация в индусском стиле?


Ну мне это интересно уже просто из принципа, кто прав в данном вопросе.
Я то всегда использую выравнивание, поскольку быстродействие важнее, а памяти
хватает чрезмерно для мной решаемых задач.
Re[11]: вопрос по синхронизации в многопоточной среде
От: Кодт Россия  
Дата: 15.07.10 20:50
Оценка:
Здравствуйте, tripol, Вы писали:

T>В данном случае как раз поможет, и без всяких Interlocked-функций. InterlockedExchange — функция использующаяся

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

Чтобы прочитать, можно сделать такое
value = InterlockedExchangeAdd(&var, 0);
value = InterlockedCompareExchange(&var, ANY_CONST, ANY_CONST);


T>InterlockedExchange генерирует memory barrier, который гарантирует последовательность выполнения операций

T>с памятью, и в данном случае это не требуется.

Атомарно читаем расшаренные данные, и при этом пытаемся выцыганить немного времени на переупорядочивании?
Перекуём баги на фичи!
Re[12]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 15.07.10 21:17
Оценка:
Здравствуйте, Кодт, Вы писали:

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


T>>В данном случае как раз поможет, и без всяких Interlocked-функций. InterlockedExchange — функция использующаяся

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

К>Чтобы прочитать, можно сделать такое

К>
К>value = InterlockedExchangeAdd(&var, 0);
К>value = InterlockedCompareExchange(&var, ANY_CONST, ANY_CONST);
К>


Обе функции требуют выравнивания по 32-битной границе, и что не дает никаких
преимуществ перед обычным чтением.

T>>InterlockedExchange генерирует memory barrier, который гарантирует последовательность выполнения операций

T>>с памятью, и в данном случае это не требуется.

К>Атомарно читаем расшаренные данные, и при этом пытаемся выцыганить немного времени на переупорядочивании?


Все же лучше чем атомарно читать + писать (как минимум в два раза быстрее).
Re[12]: вопрос по синхронизации в многопоточной среде
От: uzhas Ниоткуда  
Дата: 16.07.10 06:05
Оценка:
Здравствуйте, night beast, Вы писали:

NB>дык эта, модифицирование одной переменной несколько раз между точками следования.

NB>бородатый пример.
благодарю, что-то скобки меня с толку сбили
кстати, прикольный код, компилируемый в комо:
int a = a = a = a;
Re[13]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 16.07.10 06:16
Оценка:
Здравствуйте, tripol, Вы писали:

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


S>>так всетаки неясно насчет volatile...

S>>volatile в msdn
S>>в мсдн написано, что при каждой обращении будет считано текущее значение volatile переменной(из памяти имеется ввиду, да?). А далее говорится, что-то про Microsoft specific..там говорится о каких-то aquire и release semantics.. и что они означают я пока не понял... объясните кто-то пожалуйста)
S>>вот тут некая Алена С++ пишет, что это говорит о атомарности операций с переменной.
S>>Если это так... то это вроде то, что нужно.
S>>Вообще значение переменной меняется из одного потока, а вот считывается многими.. и если volatile действительно дает атомарность.. значит *Interlocked ф-ями можно не пользоваться. так?

T>Тут важно знать следующее:

T>* как уже было написано, атомарность чтения/записи в память на большинстве 32-бит, 64-битных архитектур(IA32, x64 в их числе) гарантируется,
T>если DWORD выровнен по 4-байтной сетке и выше. (это по умолчанию если не крутить соответствующие настройки проекта).
T>* volatile необходимо для того, что бы указать компилятору, что необходимо генерировать такой код, который
T>будет брать/записывать каждый раз значение из памяти, а не как иначе.

T>Тоесть тут два уровня: уровень компилятора(откомпилированного кода) и уровень процессора и памяти.


т.е. если я правильно понял — обойтись можно и без volatile? ведь если volatile говорит только о том, что переменная будет считана каждый раз из памяти — то какой в ней смысл, если она и так будет считана один раз в гетере..?
зы. класс — COM класс, компилятор ничего не заинлайнит.
Re[4]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 16.07.10 06:22
Оценка:
Здравствуйте, quodum, Вы писали:

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


S>>>интересно, а предыдущее значение устраивает?

S>>да. раз не успел... то ладно)

Q>На многопроцессорной системе может не успеть никогда (пока из локального кэша старое значение не вытеснится).

а можо в двух словах что такое локальный кеш? т.е. копия переменной в памяти хранится еще где-то, кроме памяти?
Re[14]: вопрос по синхронизации в многопоточной среде
От: tripol  
Дата: 16.07.10 06:55
Оценка:
Здравствуйте, sidorov18, Вы писали:

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

S>зы. класс — COM класс, компилятор ничего не заинлайнит.

Если COM, то можно обойтись.
Кроме прочего для понятности volatile можно использовать, что бы помечать,
что данная переменная или функция может быть безопасно использоваться
другими потоками.
Re[15]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 16.07.10 07:27
Оценка:
Здравствуйте, tripol, Вы писали:

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


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

S>>зы. класс — COM класс, компилятор ничего не заинлайнит.

T>Если COM, то можно обойтись.

T>Кроме прочего для понятности volatile можно использовать, что бы помечать,
T>что данная переменная или функция может быть безопасно использоваться
T>другими потоками.

а в случае с 8-и байтовой переменнной? тоже можно использовать без volatile?
Re[2]: вопрос по синхронизации в многопоточной среде
От: sidorov18 США  
Дата: 16.07.10 08:16
Оценка:
Здравствуйте, Sni4ok, Вы писали:

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


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


S>а что в данном случае не воспользоваться interlocked функциями?

Воспользоватся можно хоть boost::через_*опу.
Вопрос был в том, какого решения достаточно для нормальной работы
Re[13]: вопрос по синхронизации в многопоточной среде
От: Кодт Россия  
Дата: 16.07.10 09:16
Оценка:
Здравствуйте, tripol, Вы писали:

T>Обе функции требуют выравнивания по 32-битной границе, и что не дает никаких преимуществ перед обычным чтением.


Вообще, выравнивание — вещь хорошая. Зачем в клиентском коде от него отступаться?
Тем более, когда мы гонимся за производительностью.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.