Здравствуйте, MasterZiv, Вы писали:
MZ>tripol wrote:
>> А что, по твоему, процессор записывает в память / кэш по половине DWORD?
MZ>С уверенностью можно сказать только одно: меньше чем байт в память не MZ>записать и не считать из неё. А вот остальное ...
По умолчанию компилятор выравнивает DWORD-ы как минимум по границе в 4 байта,
а операции чтения/записи с таких адресов являются атомарными.
Re[7]: вопрос по синхронизации в многопоточной среде
Здравствуйте, 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[7]: вопрос по синхронизации в многопоточной среде
Здравствуйте, tripol, Вы писали:
T>По умолчанию компилятор выравнивает DWORD-ы как минимум по границе в 4 байта, T>а операции чтения/записи с таких адресов являются атомарными.
это верно не для всех платформ, для x86 верно
Re[12]: вопрос по синхронизации в многопоточной среде
Здравствуйте, tripol, Вы писали:
T>Ну тоесть InterlockedExchange — функция использующаяся и для чтения, но volatile необходимо, T>кстати оно присутствует в объявлении функции T>LONG __cdecl InterlockedExchange(
есть мнение, что наличие volatile говорит лишь о том, что данная функция в том числе может работать с volatile переменной, ибо навесить volatile легко, а снять тяжело
Re[13]: вопрос по синхронизации в многопоточной среде
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, tripol, Вы писали:
T>>Ну тоесть InterlockedExchange — функция использующаяся и для чтения, но volatile необходимо, T>>кстати оно присутствует в объявлении функции T>>LONG __cdecl InterlockedExchange(
U>есть мнение, что наличие volatile говорит лишь о том, что данная функция в том числе может работать с volatile переменной, ибо навесить volatile легко, а снять тяжело
Не вижу смысла не использовать volatile при доступе к переменной из разных потоков.
По коду сразу видно, что переменная или функция может использоваться из разных
потоков, что значительно облегчает программирование и устраняет неоднозначности.
Кроме того доступ к volatile переменной быстрее чем использование InterlockedExchange,
и поэтому тем более не вижу каких либо проблем для использования volatile.
Re[13]: вопрос по синхронизации в многопоточной среде
Здравствуйте, uzhas, Вы писали:
U>есть мнение, что наличие volatile говорит лишь о том, что данная функция в том числе может работать с volatile переменной, ибо навесить volatile легко, а снять тяжело
Вообще то функция воспринимает эту переменную как volatile (не volatile приводится к volatile).
Re[11]: вопрос по синхронизации в многопоточной среде
Здравствуйте, 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]: вопрос по синхронизации в многопоточной среде
Здравствуйте, 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]: вопрос по синхронизации в многопоточной среде
Здравствуйте, A.Lokotkov, Вы писали:
AL>Здравствуйте, tripol, Вы писали:
T>>По умолчанию компилятор выравнивает DWORD-ы как минимум по границе в 4 байта, T>>а операции чтения/записи с таких адресов являются атомарными.
По умолчанию — это далеко не всегда.
AL>Дабы закончить свое участие в этой дискуссии, процитирую интеловскую матчасть:
Спасибо за цитату, весь день собирался, но ленился сам искать. Короче, под win вполне может беда случиться
Re[12]: вопрос по синхронизации в многопоточной среде
Здравствуйте, tripol, Вы писали:
__>>Согласен, хотя к проблеме, поднятой топикстартером, это мало относится. И, кстати, InterlockedExchange заодно уж и эту опасность устранит.
T>Не вижу смысла каждый раз читать + писать в память тогда когда достаточно просто читать или просто писать.
То, что InterlockedExchange возвращает значение — приятный это побочный результат эффективной реализации этой функции, а не основное ее назначение.
T>Производительность как раз можно загробить там где без необходимости используются memory barriers и лишние T>записи / чтения.
T>А спецификатор volatile исключает вышеприведенную зацикленность и другие подобные возможные случаи.
volatile вполне себе может привести как раз к лишним записям/чтениям, он для этого и предназначен. Но у нас разговор уже по кругу пошел.
Re[9]: вопрос по синхронизации в многопоточной среде
Здравствуйте, _stun_, Вы писали:
__>То, что InterlockedExchange возвращает значение — приятный это побочный результат эффективной реализации этой функции, а не основное ее назначение.
Это основное ее назначение, поскольку функция называется не InterlockedWrite.
__>volatile вполне себе может привести как раз к лишним записям/чтениям, он для этого и предназначен.
Нет при операции чтения — это чтение, а при операции записи — это запись, а не все вместе.
Re[10]: вопрос по синхронизации в многопоточной среде
Здравствуйте, tripol, Вы писали:
T>И все таки, как просто считать значение переменной, если она вдруг не выровнена. T>Тут InterlockedExchange не поможет, поскольку изменяет значение...
Она может быть не выровнена, если компилятору задали явно кривое выравнивание, например, на 1 или 2 (в 2008-й студии по умолчанию 8). Вероятно, поможет InterlockedExchangeAdd с нулем в качестве второго аргумента. "Вероятно", поскольку в Windows CE, которая тоже какбэ винда, первый аргумент должен смотреть на выровненную переменную.
bloß it hudla
Re[11]: вопрос по синхронизации в многопоточной среде
Здравствуйте, 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]: вопрос по синхронизации в многопоточной среде
Здравствуйте, 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]: вопрос по синхронизации в многопоточной среде
Здравствуйте, A.Lokotkov, Вы писали:
AL>Ага, значит, я ошибся -- в большой венде тоже нельзя. Кстати, для чего может потребоваться кривое выравнивание в кошерной программе? Сериализация/десериализация в индусском стиле?
Ну мне это интересно уже просто из принципа, кто прав в данном вопросе.
Я то всегда использую выравнивание, поскольку быстродействие важнее, а памяти
хватает чрезмерно для мной решаемых задач.
Re[11]: вопрос по синхронизации в многопоточной среде
Здравствуйте, tripol, Вы писали:
T>В данном случае как раз поможет, и без всяких Interlocked-функций. InterlockedExchange — функция использующаяся T>для записи, а что ты предлагаешь использовать для чтения переменной, и тем более без volatile? T>Не вводи в заблуждение.
Чтобы прочитать, можно сделать такое
value = InterlockedExchangeAdd(&var, 0);
value = InterlockedCompareExchange(&var, ANY_CONST, ANY_CONST);
T>InterlockedExchange генерирует memory barrier, который гарантирует последовательность выполнения операций T>с памятью, и в данном случае это не требуется.
Атомарно читаем расшаренные данные, и при этом пытаемся выцыганить немного времени на переупорядочивании?