|
|
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
"Наивный чукотский юноша". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 20:19 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Лично у меня, в Seamonkey, ваши "картинки с другого сайта" просто не отображаются. Запустив тыртырнет-сексплорер я могу получить ссылку, но это мало что меняет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 20:24 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Blazkowiczredwhite90Что происходит в тот момент, когда я пытаюсь считать волатильную перменную ? У меня в каждом потоке свое закешированное значение волатильной переменной(непосредственно перед чтением), как они синхронизируются? Как выбирается самое актуальное значение? P.S. я знаю, что volatile write happens-before volatile read Грубо говоря на пальцах это так: переменная - это значение в памяти. Кэш это регистр процессора. Обычную переменную можно не читать из памяти (долго), а прочитать из регистра (быстро). Чтение volatile переменной происходит из памяти. Поэтому там актуальное значение, а не из регистра, где может быть устаревшее. Чуть менее грубо: кроме вышенаписанного, перед записью волатильной переменной из регистра процессора в память, jvm записывает (если есть) все другие регистры в память. А перед чтением волатильной переменной в регистр из памяти, jvm обновляет остальные регистры из памяти. поэтому записанное перед записью в волатил видится после чтения из волатила. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 21:01 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Ну хотя бы не буду теперь чувствовать себя идиотом, когда начинаются холливары про volatile. Причем обычно у отвечающего хватает ответить что то типа "чувак, ты не прав", там все по другому, на вопрос как кто нить кинет ссылку, которую даже сам не читал. Если кто то пытается объяснить своими словами. Его массово заклевывают, мол ты не прав, но доходчиво на общепонятных(понятных спрашивающему) примитивах никто не удосужится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 21:10 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Лично я не стал бы полагаться на это поведение. Volatile даёт определённые гарантии относительно конкретной переменной. Ладушки, а всё остальное - от лукавого. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 21:11 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovЛично я не стал бы полагаться на это поведение. Volatile даёт определённые гарантии относительно конкретной переменной. Ладушки, а всё остальное - от лукавого.Сила volatile как раз и строится на piggibacking: int x = 0; volatile int y = 0; Thread1: x = 1; y = 1; Thread2: if (y == 1) assert x == 1; Это очень мощная фича, которая очень широко применяют в конкурентном программировании. Ничего в ней "лукавого" нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 21:32 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
И, типа, от порядка объявления-следования ничего не зависит? Совсем-совсем? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 21:36 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
cdtyjv, про piggyback я тоже слышал. http://stackoverflow.com/questions/8769570/volatile-piggyback-is-this-enough-for-visiblity но минус в том, что если кто-то подумает, что это действие над волатильной переменной не нужно больше(не подумав даже о том волатильная она или нет), удалит одну строчку - всё может накрыться) chabapok Чуть менее грубо: кроме вышенаписанного, перед записью волатильной переменной из регистра процессора в память, jvm записывает (если есть) все другие регистры в память. А перед чтением волатильной переменной в регистр из памяти, jvm обновляет остальные регистры из памяти. поэтому записанное перед записью в волатил видится после чтения из волатила. хм, вижу противоречие... то есть волатильная переменная по вашему пишется в регистр процессора? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 21:37 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
DEVcoach, DEVcoachКак это все сделать за раз? Ответ: volatile. Если мы отметим переменную volatile, то JVM: 1) Не будет сохранять ее в регистрах 2) Не будет оптимизировать код вокруг нее (не будет выпиливать ее чтения, не будет ее переставлять и т.д.) 3) Вокруг ее чтения/записи компилятор добавить специальных инструкций процессора, которые почистят store buffer / invalidate queue кэшей. Обычно это делают через вызов системных функций операционной системы, которая в свою очередь исполнит нужные инструкции процессора. Это и есть volatile, что называется, "на пальцах". Заметьте, volatile кэшируются в кэшах, так же, как и все другие переменные. Кэшировать надо все и всегда, так как читать из память очень дорого. Но для обеспечения правильной видимости, volatile: 1) Форсирует подсистему памяти синхронизировать состояние кэшей. 2) Запрещает JIT-у делать оптимизации на этой переменной. а можете по каждому пункту предоставить прувы, а то смотрю мнения расходятся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:09 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovИ, типа, от порядка объявления-следования ничего не зависит? Совсем-совсем?Не понял вопрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:13 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
cdtyjvНе понял вопрос.Переставили местами порядок объявления переменных, порядок следования операторов в тексте программы. Есть класс с кучей переменных. Если одна единственная volatile выключит оптимизацию всего остального, то не пошло бы оно лесом - такое поведение? На каком фрагменте действует volatile? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:18 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
говорят, что понять как работает волатайл можно по следующему коду http://hg.openjdk.java.net/icedtea/jdk7/hotspot/file/d9f0ed25f7ed/src/share/vm/opto/memnode.cpp#l2862 кто знает ассемблер -расскажите что там написано) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:21 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
redwhite90а можете по каждому пункту предоставить прувы, а то смотрю мнения расходятся.Ну давайте для большей точности вот так скажем: 1) Не будет сохранять ее в регистрах 2) Не будет оптимизировать код вокруг нее (не будет выпиливать ее чтения, не будет ее переставлять и т.д.) 3) Вокруг ее чтения/записи компилятор добавить специальных инструкций процессора, которые почистят store buffer / invalidate queue кэшей. Обычно это делают через вызов системных функций операционной системы, которая в свою очередь исполнит нужные инструкции процессора. Ибо п.1 - это по сути одна из оптимизаций из п.2. Здесь принципиально то, что каждое чтение волатильной переменной должно сопровождаться ее реальным чтением из подсистемы "кэш-память". А сохраняет ее процессор для каких-то своих нужд в регистры или нет - дело третье. Хочет сохранить - ну пускай сохранит. Например, предположим, что у нас есть следующий код: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. И вы вызываете method1(). Как будет выглядеть assembly? Может быть так: Код: java 1. 2. А может быть вот так: Код: java 1. 2. // Вызвали метод. Первый способ - стандартный, специфицированный подход к вызову функций. Второй способ - более быстрая вариация, так называемый fastcall, так как быстрее сохранить переменную в регистр, чем записывать ее в стэк. Но в обоих случаях была создана копия волатильной переменной. Это страшно? Нет, ведь мы передаем int в метод, а примитивы передаются в методы по значению. То есть у нас просто напросто нет другого варианта, кроме как скопировать волатильную переменную. Но если бы переменная не была волатильной, то во втором случае JVM могла бы попробовать переиспользовать ее из регистра при последующем чтении. А если она волатильна, то такого переиспользования не будет. Так что не циклитесь на регистрах. Это детали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:26 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
questionerговорят, что понять как работает волатайл можно по следующему коду http://hg.openjdk.java.net/icedtea/jdk7/hotspot/file/d9f0ed25f7ed/src/share/vm/opto/memnode.cpp#l2862 кто знает ассемблер -расскажите что там написано)Это кишки компилятора, они вам никак не помогут понять volatile. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:29 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovПереставили местами порядок объявления переменных, порядок следования операторов в тексте программы. Есть класс с кучей переменных. Если одна единственная volatile выключит оптимизацию всего остального, то не пошло бы оно лесом - такое поведение? На каком фрагменте действует volatile?volatile не выключает "все остальное". Она синхронизирует состояние в момент ее чтения/записи. До/после этого можно оптимизировать все, что угодно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:31 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
cdtyjv, вроде пазл сошёлся) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:32 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
cdtyjvvolatile не выключает "все остальное". Она синхронизирует состояние в момент ее чтения/записи. До/после этого можно оптимизировать все, что угодно.Я, таки, нашёл How will the JMM change under JSR 133 и понял то, о чём вы говорите. Возражения против использования такого подхода в прикладном коде - остаются: завтра автор (по забывчивости) или кто другой (по незнанию) переставит местами два оператора потому, что это "эстетичнее", а на работу алгоритма в текущем потоке - никак не влияет. И всё - синхронизация с другими потоками разрушена. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 22:53 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
И, кстати, даже без переупорядочивания ... Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. Вроде - всё хорошо. Но а и б "на трубе не сидят" и JIT невозбранно может кешировать их в регистрах. Если такое кэширование произошло до записи "изменчивой" переменной, то её перечитывание из памяти (само по себе) не отменит регистровые копии. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 23:06 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Мой пример - некорректный, но дальше думать, т.к. возражения всё равно остаются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 23:12 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. Пример идиотский, но суть проблемы, думаю понятна: изменчивость - плохой барьер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 23:33 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Basil A. Sidorov Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. Пример идиотский, но суть проблемы, думаю понятна: изменчивость - плохой барьер.Ну так давайте будем рассматривать какой-нибудь "хороший" пример, который действительно можно использовать на практике. Вашей претензией является неочевидность. С этим никто и не спорит. Но с другой стороны, никто и не говорит, что этот подход надо использовать в регулярной практике. Piggibacking часто применяют в замысловатых неблокирующих алгоритмах, когда хотят максимально расслабить синхронизацию, и т.д.. Рядовой программист, который может бездумно "переставить две строчки" в такой код не полезет. Для сложных задач - сложный код, для простых - простой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.07.2014, 23:44 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
cdtyjvВашей претензией является неочевидность. С этим никто и не спорит. Но с другой стороны, никто и не говорит, что этот подход надо использовать в регулярной практикеСтранные вы люди ... Зачем обсуждать (реально) тёмные детали устройства процессора, если всё, что достаточно знать об изменчивости, укладывается вот в это предложение:Fixing the Java Memory ModelThis process guarantees that when a variable is written by one thread during a synchronized block protected by a given monitor and read by another thread during a synchronized block protected by the same monitor, the write to the variable will be visible by the reading thread? Т.е. раньше гарантии видимости распространялись только на саму переменную, теперь - на все предыдущие присваивания. Что улучшает синхронизацию, за счёт незначительной просадки производительности. P.S. А пример мой относился к тому, что JIT имеет полное право модифицировать код до: Код: sql 1. 2. 3. 4. 5. 6. 7. Однопоточная семантика осталась прежней, многопоточная - разрушена. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2014, 00:04 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovЗачем обсуждать (реально) тёмные детали устройства процессора, если всё, что достаточно знать об изменчивости, укладывается вот в это предложение:Fixing the Java Memory ModelThis process guarantees that when a variable is written by one thread during a synchronized block protected by a given monitor and read by another thread during a synchronized block protected by the same monitor, the write to the variable will be visible by the reading thread? Т.е. раньше гарантии видимости распространялись только на саму переменную, теперь - на все предыдущие присваивания. Что улучшает синхронизацию, за счёт незначительной просадки производительности.Всего существует два "типа синхронизации": 1) Release semantics - после записи некоторой переменной она становится потенциально видна другим потокам, так же, как и все записи, которые шли до нее. 2) Acquire semantics - после чтения некоторой переменной, все последующие чтения других переменных должны вычитать более новые значения "себя". Все, другого не дано. Предложение, которое вы привели описывает только synchronized. А работает он так: acquire() тело_synzcronized_блока release() volatile работает вот так: запись_volatile_переменной release() acquire() чтение_volatile_переменной Соответственно, все те трюки с piggibacking, которые возможны с volatile, возможны и с synchronized. Вот это работает: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. Thread 2: Код: java 1. 2. 3. 4. 5. 6. 7. 8. Что бы не верить на слово, что оно работает именно так, а понимать почему оно именно так было спроектировано и именно так работает, и надо знать и про JIT, и про store buffer / invalidate queue. Это улучшает понимание протекающих процессов, а от этого еще никому хуже не стало. Basil A. SidorovОднопоточная семантика осталась прежней, многопоточная - разрушена.Ничего не разрушено ... так как в вашем примере многопоточная семантика изначально была некорректной. Нечего разрушать. Предлагаю оставить этот бессмысленный пример, и рассматривать что-то реально применимое. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2014, 00:24 |
|
||
|
Concurrency Vs multithreading
|
|||
|---|---|---|---|
|
#18+
redwhite90chabapok Чуть менее грубо: кроме вышенаписанного, перед записью волатильной переменной из регистра процессора в память, jvm записывает (если есть) все другие регистры в память. А перед чтением волатильной переменной в регистр из памяти, jvm обновляет остальные регистры из памяти. поэтому записанное перед записью в волатил видится после чтения из волатила. хм, вижу противоречие... то есть волатильная переменная по вашему пишется в регистр процессора? Не очень понял контекст вопроса. Но вцелом да: процессору, чтобы выполнить какую-либо операцию над двумя переменными, надо как минимум одну загрухить в регистр, и результат операции оказывается в регистре. Так, чтобы произвести операцию над двумя ячейками памяти и результат записать сразу в память - в х86 такого нет. И даже если где-то и есть, это большая редкость. То есть да, волатил когда-нибудь в регистр пишется, если операции над волатилом есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2014, 09:35 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38688429&tid=2126936]: |
0ms |
get settings: |
4ms |
get forum list: |
8ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
146ms |
get topic data: |
6ms |
get forum data: |
1ms |
get page messages: |
33ms |
get tp. blocked users: |
1ms |
| others: | 206ms |
| total: | 409ms |

| 0 / 0 |
