|
|
|
Reordering
|
|||
|---|---|---|---|
|
#18+
есть такой код Код: java 1. 2. 3. 4. 5. 6. 7. 8. в первом потоке может случится реордеринг и второй поток словит NPE. Как сделать, чтобы первый поток всегда выполнял строку Код: plaintext Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:20 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:26 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Лагман Код: java 1. И? Сначала выполнится reslitReady = reslit != null, потом reslit = calc(); и второй поток будет вечно ждать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:30 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Blazkowiczvolatile? Каким образом volatile спасет от reordering? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:33 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zu, реордеринг возможен, если инструкции независимы друг от друга. Если мы пишем reslit != null то это уже зависит от reslit, и реордеринга не будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:34 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Этот пост раскручиваете? http://www.javaspecialist.ru/2011/06/java-memory-model.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:37 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Лагманzig zu, реордеринг возможен, если инструкции независимы друг от друга. Если мы пишем reslit != null то это уже зависит от reslit, и реордеринга не будет. Согласен, так наверное будет работать. Давайте тогда усложним задачу )) Код: java 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:38 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zuBlazkowiczvolatile? Каким образом volatile спасет от reordering? Если ты пришёл в форум за вопросом - то должен соблюдать протокол. Тебе задали вопрос - ответь на него. Если ты сам задаёшь вопросы - то сообщество решит что ты слишком умён и тебе помогать не стоит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:39 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
ЛагманЭтот пост раскручиваете? http://www.javaspecialist.ru/2011/06/java-memory-model.html Нет, я его прочитал и не понял момент про который спрашиваю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:39 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Теперь calc() в экспшен засунуть ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:39 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Лагманну, т.е. в try-catch в этом случае тоже реордеринга не будет? ну то есть если calc будет в try-catch а после этой конструкции установвка флага? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:45 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zu, На самом деле я не знаю, может гуру многопоточности подскажут ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 15:49 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
ЛагманЭтот пост раскручиваете? http://www.javaspecialist.ru/2011/06/java-memory-model.html Кстати, там же есть ссылка https://blogs.oracle.com/vmrobot/entry/модель_памяти_java , которая и является первоисточником всех статей выше, с изменененными примерами и прочей водой. zig zuBlazkowiczvolatile? Каким образом volatile спасет от reordering? "... и на мой взгляд у этих правил есть только одно следствие, касающееся порядка операций, используемое на практике: операции чтения и записи volatile переменных не могут быть переупорядочены с операциями чтения и записи других volatile и не-volatile переменных. Это следствие делает возможным использование volatile переменной как флага, сигнализирующем об окончании какого-либо действия, например: ...". Так что подойдет для двух случаев. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:11 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Лагман Код: java 1. Это не работает. Во-первых, это не защищает от реордеринга, так как те же спекулятивные чтения никто не отменял. Во-вторых, потому что если бы вы даже смогли таким образом предовтратить реордеринг, у вас все равно не будет гарантий того, что другой поток увидит изменения именно в таком порядке. Погуглите про store buffer и invalidate queue. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:29 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Лагманzig zu, реордеринг возможен, если инструкции независимы друг от друга. Если мы пишем reslit != null то это уже зависит от reslit, и реордеринга не будет.К сожалению, это не так. Out-of-order execution это значительно более сложная вещь, чем "раз зависимы, значит не зареордерятся". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:30 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
0FD, Отлично! volatile спасет мир. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:31 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zuесть такой код Код: java 1. 2. 3. 4. 5. 6. 7. 8. в первом потоке может случится реордеринг и второй поток словит NPE. Как сделать, чтобы первый поток всегда выполнял строку Код: plaintext Код: plaintext 1) Самый простой - объявить reslitReady volatile. 2) Можно обернуть эти два участка кода в synchronized на одном и том же мониторе. 3) Ну и всевозможные способы, производные от первых двух. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:33 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Вообще, мужики, потерпите, ждать осталось не долго - скоро будет готова моя первая часть тренинга по multithreading. В эту часть войдет вся теория по JMM, synchronized, volatile, final, а так же вопросы остановки потоков. Вчера как раз весь день рисовал схемки, как кэши работают :-) Можете уже бронировать места ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:38 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvВообще, мужики, потерпите, ждать осталось не долго - скоро будет готова моя первая часть тренинга по multithreading. В эту часть войдет вся теория по JMM, synchronized, volatile, final, а так же вопросы остановки потоков. Вчера как раз весь день рисовал схемки, как кэши работают :-) Можете уже бронировать места Тренинг будет выглядеть так: "Погуглите про ... " ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:47 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvЛагманzig zu, реордеринг возможен, если инструкции независимы друг от друга. Если мы пишем reslit != null то это уже зависит от reslit, и реордеринга не будет.К сожалению, это не так. Out-of-order execution это значительно более сложная вещь, чем "раз зависимы, значит не зареордерятся". Наверное Out-of-order execution действительно крутая и очень сложная штука, но не могли бы вы на пальцах объяснить, как вот такой код может подвергнутся реордеренгу? Код: java 1. 2. с учетом того, что основное правило реордеренга гласит - после реордеринга поведение программы не должно меняться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:57 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zuс учетом того, что основное правило реордеренга гласит - после реордеринга поведение программы не должно меняться. Вероятно имеется ввиду, не то что могут поменять местами строки Java кода. А более мелкие операции уровня как байт-кода так и нативного после JIT компиляции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 16:59 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zuНаверное Out-of-order execution действительно крутая и очень сложная штука, но не могли бы вы на пальцах объяснить, как вот такой код может подвергнутся реордеренгу?Например, speculative branch prediction. Как это может произойти: 1) Процессор начинает выполнять calc(), и натыкается там на чтение значения, которого нет в кэшах. 2) Из-за этого процессор вынужден отправить запрос в память на получение этого значения; длительность этого чтения может составлять сотни тактов. 3) Что бы не стоять эти такты без дела, процессор начинает фигачить следующие инструкции (пошел out-of-order execution); 4) Процессор натыкается "reslitReady = reslit != null" 5) Вроде бы дело дрянь, так и так придется ждать окончание долго чтения в calc(). Но процессор находит выход: он делает спекулятивное предположение, что, например, reslit != null в будущем будет true, и присваивает reslitReady = true. 6) Далее, если у вас есть что-то вроде "if (reslitReady) { ... }", процессор попытается спекулятивно выполнить какие-то инструкции из этого бранча. 7) Наконец, нам приходит ответ на чтение. Если процессор угадал результат - все круто, идем дальше. Если не угадал - откатываемся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 17:15 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjv, а вот в тот момент, когда процессор начал заниматься предсказаниями и выполнил одно из них "присваивает reslitReady = true", это вот предсказанное значение уже может увидеть второй поток? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 17:25 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zuа вот в тот момент, когда процессор начал заниматься предсказаниями и выполнил одно из них "присваивает reslitReady = true", это вот предсказанное значение уже может увидеть второй поток?Теоретически - да. Как это работает на практике в конкретном процессоре - хз. Как бы то ни было, вам, как для Java-разработчику, должно быть пофиг на то, из-за чего именно один поток видит изменения не в том порядке. Это может быть компилятор (напр. http://preshing.com/20120625/memory-ordering-at-compile-time/#out-of-thin-air), это может быть процессор, это могут быть застрявшие в store buffer значения, и т.д. Разбираться в этой кухне особого смысла нет. Вас должен волновать сам факт того, что это возможно. Когда пишете многопоточные программы, всегда исходите из следующего предположения: ПравилоЕсли у меня есть переменная, с которой работают несколько потоков, и один из них в нее пишет, то в отсутствие synchronized-with отношений другие потоки могут увидеть в этой переменной непредсказуемое значение.Это может быть устаревшее значение. Это может быть текущее значение. Это может быть ни то ни другое, а вообще какая-то полная хрень. Не важно. Важно то, что вы не можете на это значение полагаться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 17:46 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zucdtyjv, а вот в тот момент, когда процессор начал заниматься предсказаниями и выполнил одно из них "присваивает reslitReady = true", это вот предсказанное значение уже может увидеть второй поток? Есть два способа написания параллельных программ в java. 1. Учите JMM и строго следуете ей. Если сказано "порядок гарантируется с помощью synchronized или volatile"- значит используете. 2. Пытаетесь предсказать логику runtime-компилятора и надеетесь, что угадали верно. Второй подход может и сэкономит пару тактов за час. Но когда стрельнёт- ошмётки мозгов долго будут соскребать со стенки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2014, 20:42 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
На мой взгляд reordering чуть-чуть демонизируется. Строки и инструкции java-кода одного Thread'а при исполнении никогда физически не меняются местами, а выполняются одна за другой. Компилятор, интерпретатор, JIT-компилятор и прочие процессоры могут чутка видоизменить код, например, заменить конкатенацию строк, убрать ненужный synchronized, заменить вызов метода на inline-код или даже поменять местами команды процессора. Но результат (после выполнения каждой инструкции) будет 100% идентичен последовательному выполнению инструкций java-кода. По приведенной выше ссылке: http://www.javaspecialist.ru/2011/06/java-memory-model.html .. Тут еще важно отметить, что для выполнения операций в рамках одного потока, спецификация JVM разрешает делать только такой reordering, который приводит к абсолютно тем же результатам, если бы все операции выполнялись в порядке указанном в исходном коде с точки зрения потока, в котором этот код выполняется. Т.е. в одном потоке reordering никогда не проявляется. .. Список операций связанных отношением happens-before: .. В рамках одного поток любая операция happens-before любой операцией следующей за ней в исходном коде .. И еще по другой приведенной выше ссылке: https://blogs.oracle.com/vmrobot/entry/модель_памяти_java .. Существует несколько основных правил для отношения 'происходит раньше': .. в одном потоке любое действие происходит раньше любого действия, указанного в программе позже (т.е. с точки зрения потока его действия выполняются в порядке, указанном в программе) .. И первоисточник: JSR-133: JavaTM Memory Model and Thread Specification.. Happens-Before Relationship: .. Each action in a thread happens before every subsequent action in that thread .. (И никакой out-of-order execution не повлияет на это. Это проблемы процессора. Если он отработал что-то напрасно, исходя из ложного предположения, то пусть сам и расхлебывает это: откатывается, перенакатывается - java-разработчика это не касается). Reordering вообще вводится и рассматривается лишь как результат взаимодействия двух Thread'ов. Reordering при выполнении строк одного Thread'а возможен только с точки зрения стороннего Thread'а - наблюдателя. Типа наблюдатель может увидеть результат выполнение Thread'ом некой строки кода ПОСЛЕ того, как тот же наблюдатель увидит результат выполнение этим Thread'ом последующей строки кода. И все. Чтобы избежать такого виртуального reordering'а, надо следовать приведенным уже до меня правилам. Они простые. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 19:26 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
"В этой нитке" - да. А вот если ниток больше одной и они хоть как-то взаимодействуют ... Возможны ньюансы, в общем. И чем больше ниток с ядрами, их исполняющими - тем суровее будут ньюансы. P.S. На моём домашнем Sempron (не X2) будет корректно работать куча кода, которая начнёт сбоить на каком-нибудь X2 или, там, Core Duo. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 20:33 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zucdtyjvпропущено... К сожалению, это не так. Out-of-order execution это значительно более сложная вещь, чем "раз зависимы, значит не зареордерятся". Наверное Out-of-order execution действительно крутая и очень сложная штука, но не могли бы вы на пальцах объяснить, как вот такой код может подвергнутся реордеренгу? Код: java 1. 2. с учетом того, что основное правило реордеренга гласит - после реордеринга поведение программы не должно меняться. Такого не может быть такого т.к. out-of-order execution не может нарушить data-dependency. Хотя тут видимо вообще в термин OOOE какой-то иной смысл вкладывается т.к. всегда это было такое архитектурное решение, которое позволяло выполнять несколько инструкций, если они не требовали одного и того же функционального юнита и не имели зависимостей по данным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 21:18 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovА вот если ниток больше одной и они хоть как-то взаимодействуют ну дак, они взаимодействуют по контракту. Не абы как пришлось. Либо критическая секция тормозит поток, либо режьте куски БЛ без взаимодействия. Иначе теряется смысл параллельной обособленной работы потока. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 21:28 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
J.SergeНа мой взгляд reordering чуть-чуть демонизируется. +1 Точно подмечено. В ситуации отсутствия гонок весь этот сферический "реордеинг" в вакууме может быть исключительно результатом операций, которые допустимы конкретной для железки с поправкам на JMM*. А когда гонки есть, то JMM никаких детерминированных сценариев выполнения не гарантирует. Евангелие от Джеймса Гослинга 17.4.3 If a program has no data races, then all executions of the program will appear to be sequentially consistent. * Это отягощается тем, что тестов JMM под разные классы железяк не существует наверное вообще т.к. вопрос "а не написать ли нам такое?" был поставлен лишь во второй половине в прошлого года. Так что приятного кодирования на экзотических архитектурах ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 21:32 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwaТакого не может быть такого т.к. out-of-order execution не может нарушить data-dependency. Хотя тут видимо вообще в термин OOOE какой-то иной смысл вкладывается т.к. всегда это было такое архитектурное решение, которое позволяло выполнять несколько инструкций, если они не требовали одного и того же функционального юнита и не имели зависимостей по данным.Да может, может. Кто вам сказал, что переставление этих строк сломает программу в однопоточном режиме? Почему мы не можем попробовать предугадать булеан из calc(), и попробовать спекулятивно пойти дальше из какого-то конкретного предположения (напр, что он вернет true), а если мы ошебемся - откатить изменения? http://en.wikipedia.org/wiki/Branch_predictor Я уже выражал эту мысль - нет смысла рассуждать о том, может он там что-то переставить или нет. Для нас это не имеет вообще никакого значения. Ну окей, не переставил он. Зато, например, переменная reslit расшарена между потоками, а потому для консистентного изменения нужно, скажем 20 тактов, а переменной reslitReady мы владеем эксклюзивно, и можем поменять ее в кэша за 1 такт. Вы итоге результат будет таким же, как если бы там был реордеринг - мы сначала увидим второе, а уже потом первое. С точки зрения программиста разницы никакой. Вы еще учтите, что каждый новый процессор, каждая новая версия JVMки могут иметь новые навороты. Сегодня у нас один механизм когерентности кэшей, завтра другой. Сегодня JIT переставляет инструкции с опаской, а завтра его заоптимизировали под конкретную платформу, и он начал их нещадно реордерить. Нам, джавистам, на это по-хе-рам . У нас есть JMM, которая снимает эту головную. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 21:37 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwaВ ситуации отсутствия гонок весь этот сферический "реордеинг" в вакууме может быть исключительно результатом операций, которые допустимы конкретной для железки с поправкам на JMM*. А когда гонки есть, то JMM никаких детерминированных сценариев выполнения не гарантирует.И это так же неверный вывод. Там четко написано: не просто "will be sequentially consistent", " appear to be sequentially consistent". Не "является консистетным", а "выглядит консистетным", то есть дает предсказуемые результаты. А уж каким образом мы достигаем этих результатов - с реордерингами, или без оных, это уже дело третье. Вы почитайте последние дискуссии в concurrency-interest. Там зубры вроде Дага и Шипилева как раз об этом писали, недавно. А именно: знаменитый JSR 133 Cookbook от Дага, где расписано, какие барьеры куда ставить, это консервативный подход . Но если, например, у вас будут какие-то глобальные эвристики, позволяющие точно знать, нужен ли в конкретном месте барьер или нет, то можно на лету решать ставить его, там или нет. Например, вот у нас запись в volatile, вроде как надо release семантику замутить. Но этот volatile нужен будет только одному другому треду, и то, когда у писателя точно переполнится store buffer, и он точно запишет это значение, а поток-читатель к тому вреени точно пройдется по своей текущей invalidate queue и точно увидит все актуальные значения. Ну и отлично, тогда мы вообще не будем туда никаких барьеров пихать, и без них сработает. Это так, фантазия, которая возможно вообще никакого отношения к реальности не имеет, и не реализуема. Но тем не менее, она демонстрирует идею: не "является консистентным", а "выглядит консистентным", это разные вещи. И опять таки - нам пофиг на это, у нас есть JMM. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 21:47 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvschwaТакого не может быть такого т.к. out-of-order execution не может нарушить data-dependency. Хотя тут видимо вообще в термин OOOE какой-то иной смысл вкладывается т.к. всегда это было такое архитектурное решение, которое позволяло выполнять несколько инструкций, если они не требовали одного и того же функционального юнита и не имели зависимостей по данным.Да может, может. Кто вам сказал, что переставление этих строк сломает программу в однопоточном режиме? Почему мы не можем попробовать предугадать булеан из calc(), и попробовать спекулятивно пойти дальше из какого-то конкретного предположения (напр, что он вернет true), а если мы ошебемся - откатить изменения? Только дело в том, что в коде выше ничего не надо предугадывать. Есть значение из какого-то расчета и потом это значение используется для следующего расчета. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 22:31 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwaТолько дело в том, что в коде выше ничего не надо предугадывать. Есть значение из какого-то расчета и потом это значение используется для следующего расчета.Ну опять двадцать пять :-) Кто вам сказал, что не надо предугадывать? Вы это за процессор решили? В этом то и заключается speculative branch prediction, что мы можем вычислить reslitReady, не имея в руках reslit. Например, благодаря тому, что последние 1000 раз calc() возвращал true. Но я еще раз повторю, даже жирным выделю: нет никакого смысла спорить о том, что именно там происходит в кишках. Это ничего не изменит, гарантий видимости как не было, так и нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 22:40 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvВообще, мужики, потерпите, ждать осталось не долго - скоро будет готова моя первая часть тренинга по multithreading. В эту часть войдет вся теория по JMM, synchronized, volatile, final, а так же вопросы остановки потоков. Вчера как раз весь день рисовал схемки, как кэши работают :-) А зачем рисовать схемки, если cdtyjv.. нет никакого смысла спорить о том, что именно там происходит в кишках. Это ничего не изменит, гарантий видимости как не было, так и нет. Держаться больше нету сил. Тренинг будет такой же сильный, как предыдущий? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 23:12 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zu0FD, Отлично! volatile спасет мир. Мир, может, и спасет, а вас - нет. Судя по всему, вы пытаетесь сделать передачу данных между потоками без использования стандартных механизмов типа BlockingThread и synchronized блоков. Это в принципе возможно, но сначала надо научится правильно пользоваться стандартными механизмами - synchronized, volatile, ReentrantLock, Atomic*, затем выучить JMM, затем то, что появится к этому времени в Java9... А без этого бэкграунда у вас сегодня будет работать, а завтра - нет, и из проекта вы уже ушли, а пришедший вам на замену программист будет слать прокляться на вашу голову. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 23:29 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zuесть такой код Код: java 1. 2. 3. 4. 5. 6. 7. 8. А это происходит циклически или одноразово? Если циклически, то второй thread должен еще сбросить reslitReady, а первый ждать этого сброса прежде чем устанавливать reslitReady второй раз. Почему бы вам просто не использовать очередь - даже если через нее будет передаваться единственное зyачение? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 23:35 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvschwaТолько дело в том, что в коде выше ничего не надо предугадывать. Есть значение из какого-то расчета и потом это значение используется для следующего расчета.Ну опять двадцать пять :-) Кто вам сказал, что не надо предугадывать? Вы это за процессор решили? В этом то и заключается speculative branch prediction, что мы можем вычислить reslitReady, не имея в руках reslit. Например, благодаря тому, что последние 1000 раз calc() возвращал true. Но я еще раз повторю, даже жирным выделю: нет никакого смысла спорить о том, что именно там происходит в кишках. Это ничего не изменит, гарантий видимости как не было, так и нет. При этом если знать, что код работает на каком-нибудь интелле с TLO + WC, то все будет гаратироваться хотя никаких гарантий от JMM у нас нет. Во как. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 23:40 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwacdtyjvпропущено... Ну опять двадцать пять :-) Кто вам сказал, что не надо предугадывать? Вы это за процессор решили? В этом то и заключается speculative branch prediction, что мы можем вычислить reslitReady, не имея в руках reslit. Например, благодаря тому, что последние 1000 раз calc() возвращал true. Но я еще раз повторю, даже жирным выделю: нет никакого смысла спорить о том, что именно там происходит в кишках. Это ничего не изменит, гарантий видимости как не было, так и нет. При этом если знать, что код работает на каком-нибудь интелле с TLO + WCСС, то все будет гаратироваться хотя никаких гарантий от JMM у нас нет. Во как. fixed. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 23:42 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwaПри этом если знать, что код работает на каком-нибудь интелле с TLO + WC, то все будет гаратироваться хотя никаких гарантий от JMM у нас нет. Во как.Не знаю, что такое TLO, TSO может быть имелось ввиду? Как бы то ни было, вот код, который на моем Intel Core i5 никаких гарантий не дает, и при этом не работает: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 23:56 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
J.SergeНа мой взгляд reordering чуть-чуть демонизируется. Строки и инструкции java-кода одного Thread'а при исполнении никогда физически не меняются местами, а выполняются одна за другой. Читайте доки. У тебя есть две операции записи в память (два присвоения). Компилятор не переупорядочил, JIT не трогал, но процессор, уж так пришлось, запишет их из кэша в основную память другом порядке. Его право. И если еть другой поток, который исполняется на другом процессоре, то в каком порядке он увидит изменения переменных зафисит от такого количества параметров (включая состояние кэшей этого процессора), что об этом лучше не думать вообще, пока ты не понимаешь ВСЁ это. Ещё раз- если не полного понимания микроархитектуры, процессоров, включая их взаимодействие в многопроцессорной системе - делайте строго по рекомендациям на основе JMM и не думайте более ни о чём. Если вам приспичило заняться высокочастотным трейдингом или ещё чем- то вы должны знать точно процессор, на котором считаете, понимать всю работу кэшей и т.п. Тогда, если захотите, можете отступать от рекомендаций JMM. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 08:43 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Alexey Tomin, спасибо за прочтение и понимание того, что я написал выше ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 08:52 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvПочему он не останавливается? А хз. Может из-за процессора, может из-за JITа, может еще из-за чего-то. В реальных задачах мне нафиг не упало возиться с PrintAssembly, и вдуплять, что именно там произошло. Код не работает. Важно не задрачиваться из-за конкретных причин, а знать, как устранить проблему. Да знаете, пробовали ведь // private volatile int val; если убрать комментарий, работает ведь. cdtyjv, 15409479 тут масштабы что делает программа и процессор несколько несопоставимы, и это мягко сказано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 10:38 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Кстати, можете помучить вот этот код: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. PlainValueHolder - не работает; VolatileValueHolder - работает; PlainUnsafeValueHolder - работает; ReadVolatileValueHolder - работает; WriteVolatileValueHolder - не работает; WriteOrderedValueHolder- не работает; MonitorEnterValueHolder - работает. Какие можно из этого сделать выводы? Обычный доступ не работает, это понятно. Чтения через acquire работают (VolatileValueHolder, ReadVolatileValueHolder, MonitorEnterValueHolder), это тоже понятно. Но вот какого хрена работает PlainUnsafeValueHolder без всяких барьеров? И почему не работает WriteVolatileValueHolder с записью с release? Да очень просто - значит это не железяка выкобенивается, а компилятор. Когда я делаю обычное чтение через Unsafe, явно задав адрес, откуда читать - он видит апдейт. А обычные чтения апдейт не видят, так как компилятор то ли сделал себе локальную копию, то ли еще что-то. А acquire семантика убивает эту оптимизацию, тем самым позволяя нам таки увидеть изменившееся значение. Это еще раз к тезису о том, что не так важно, понимать, почему именно программа ведет себя некорректно. Важно понимать принципы решения этих проблем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 11:34 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvschwaПри этом если знать, что код работает на каком-нибудь интелле с TLO + WC, то все будет гаратироваться хотя никаких гарантий от JMM у нас нет. Во как.Не знаю, что такое TLO, TSO может быть имелось ввиду? Как бы то ни было, вот код, который на моем Intel Core i5 никаких гарантий не дает, и при этом не работает: Конечно такой код не работает. И если это был самый последний код, которые выполняется при завершении программы, то она бы не остановилась. А вот если он был бы расположен где-то в глубине, когда дальше будут идти запаси и обращения к "общим" локациям памяти, то все бы сработало как надо. Только это факт того, что в конкретном случае это работать будет, а не рекомендация к тому, что так делать нужно. p.s. TLO = Total Lock Order ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 11:52 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwaИ если это был самый последний код, которые выполняется при завершении программы, то она бы не остановилась. А вот если он был бы расположен где-то в глубине, когда дальше будут идти запаси и обращения к "общим" локациям памяти, то все бы сработало как надо.Вы почитайте мой пост выше с анализом причин этого, и поймете, что данный код ломается независимо от "глубины". schwaTLO = Total Lock OrderГугл такого не знает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 12:05 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Вот апдейт тестового кода, который демонстрирует, что никакая "глубина" нас не спасает: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 12:34 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjv, Это называется давай обманем jit, пусть думает что это обычная, а мы будет использовать семантику volatile и посмотрим что будет. Вот что Вы ожидаете когда определяете protected int val; а используете unsafe.getIntVolatile(this, offset); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 12:50 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
0FD , Я ничего не ожидаю, я лишь демонстрирую, как разные способы чтения влияют на то, завершится программа или нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 13:02 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvschwaИ если это был самый последний код, которые выполняется при завершении программы, то она бы не остановилась. А вот если он был бы расположен где-то в глубине, когда дальше будут идти запаси и обращения к "общим" локациям памяти, то все бы сработало как надо.Вы почитайте мой пост выше с анализом причин этого, и поймете, что данный код ломается независимо от "глубины". Только вот с тем, что это код будет ломаться никто и не спорил ;) cdtyjvГугл такого не знает. Невезение с гуглом. Мне он выдает цитаты из соответствующих мануалов в первых же результатах поиска. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 17:11 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwaТолько вот с тем, что это код будет ломаться никто и не спорил ;)Ну вы же сказали, что при обращении к "общим" локациям памяти все будет нормально. Как видно из кода, не будет. schwaНевезение с гуглом. Мне он выдает цитаты из соответствующих мануалов в первых же результатах поиска.Поделитесь ссылочкой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 17:23 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Petro123ну дак, они взаимодействуют по контрактуЭтот контракт реализует вполне конкретный человек. Который может понавтыкать в своём коде всяческих чудес, которые прекрасно пройдут все юнит-тесты и начнут глючить, когда встанут под промышленную нагрузку. Не всегда, а так ... Время от времени, но всегда не ко времени. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 19:23 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovPetro123ну дак, они взаимодействуют по контрактуЭтот контракт реализует вполне конкретный человек. Который может понавтыкать в своём коде всяческих чудес, которые прекрасно пройдут все юнит-тесты и начнут глючить, когда встанут под промышленную нагрузку. Не всегда, а так ... Время от времени, но всегда не ко времени. Тут 2 момента: - библиотеки...IDE...ЯП должен помогать программисту не писать Г. Так, например, в Delphi для потока, нужно отнаследоваться от класса Поток. - сам программист конечно тоже выполняет контракт. И не запускает поток, пока все данные для него не готовы. А если уж припёрло на всём ходу использовать глобальную переменную, то ставь критическую секцию Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... А в одном потоке все инструкции должны идти ожидаемо, и так как написано). IMHO ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2014, 23:58 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Petro123Тут 2 момента: - библиотеки...IDE...ЯП должен помогать программисту не писать Г."Охренеть! Дайте две!" Так, например, в Delphi для потока, нужно отнаследоваться от класса ПотокВ Java, что характерно - тоже. Ну или интерфейс реализовать соответствующий.сам программист конечно тоже выполняет контрактЕсть такой термин - "функциональная неграмотность". Это когда человек может читать, но не может понимать прочитанное. Толку с вашего "тоже выполняет", если конкретный программист ни уха ни рыла в конкурентном программировании? Он или засинхронизируется насмерть и будет работать в один поток или сделает глюкающий код. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 03:48 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
zig zucdtyjv, а вот в тот момент, когда процессор начал заниматься предсказаниями и выполнил одно из них "присваивает reslitReady = true", это вот предсказанное значение уже может увидеть второй поток? Нет, не может. Все сделано так, что для программиста нет разницы, делал процессор спекулятивное выполнение или нет - разве что общее время получается разным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 11:28 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Basil A. Sidorov, 1. Именно библиотеки или компилятор)). Например, для установки глобального хука в Вин32 (перехват клавиатуры), передавая функцию класса - у вас код просто не скомпилится. Можно передать только неклассовую (в Delphi). Ну и т.д....много есть примеров помощи)) 2. Если он неграмотен - нефиг потоки писать. Они нужны не так много мест. Загрузил хотя бы одним потоком все ядра)). Пусть пишет прикладной код...или сервлеты. Там потоки снаружи и не видны...контейнер помогает. Удачи! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 11:59 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
rfqВсе сделано так, что для программиста нет разницы, делал процессор спекулятивное выполнение или нет я тоже за это imho) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 12:00 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Petro123Загрузил хотя бы одним потоком все ядра)). :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 12:03 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
rfqНет, не может. Все сделано так, что для программиста нет разницы, делал процессор спекулятивное выполнение или нет - разве что общее время получается разным.Ну вот кто вам такое сказал? Даже если процессор спекулятивно пошел по ошибочному бранчу, и начал что-то писать, это вовсе не значит, что sequential consistency сломается в потоке, в котором эта спекуляция произошла. Тем не менее, большинство (если не все) распространенных процессоров так не делают. Не потому, что это невозможно в принципе, а потому что просто инженеры решили пойти другим путем. Вот, что написано в одной из диссертаций ( http://www3.ece.neu.edu/~yilmazer/thesis/thesis.pdf) на эту тему: AYSE YILMAZERTo maintain the illusion of sequential consistency, a store instruction cannot write its value to memory until it becomes the oldest (i.e., non-speculative) instruction in the processor.То есть да, пока мы не узнаем гарантированно, что данный бранч не является спекулятивным, мы не будем писать это в память. А следовательно, другие потоки не увидят спекуляцию. НО! Далее идет следующее замечание: AYSE YILMAZERIn this study, we did not consider the multiprocessors based on uniprocessors that may speculatively execute store instructions, such as the speculative versioning cache of Multiscalar [22], or Levo [24].О как оно оказывается. Есть процессоры, которые могут спекулятивно писать в память. И если вы сейчас сидите на каком-нибудь Интеле, который это не делает, это не означает, что следующее поколение их же процессоров этого делать не будет. В десятый раз поторюсь: рассуждать на тему того, что именно может делать какой-то абстрактный процессор в вакууме, это все от лукавого. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 12:17 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjv И если вы сейчас сидите на каком-нибудь Интеле, который это не делает, это не означает, что следующее поколение их же процессоров этого делать не будет. Интересно, не знал о Мultiscalar и Levo. Тем не менее, речь-то идет о Java, и даже если она будет портирована на подобные экзотические процессоры, я думаю, что спекулятивная запись в память будет зарублена. Во всяком случае, я сомневаюсь, что такая запись в память допускается спецификацией JVM. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 13:36 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvAYSE YILMAZERIn this study, we did not consider the multiprocessors based on uniprocessors that may speculatively execute store instructions, such as the speculative versioning cache of Multiscalar [22], or Levo [24].О как оно оказывается. Есть процессоры, которые могут спекулятивно писать в память. И если вы сейчас сидите на каком-нибудь Интеле, который это не делает, это не означает, что следующее поколение их же процессоров этого делать не будет. А точно программа это поведение сможет обозреть, если вместе с введением этих оптимизаций идут правки в протоколы конгерентности кэшей и др. ? Просто в противном случае подобная оптимизация может сломать даже корректную программу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 14:52 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
rfqТем не менее, речь-то идет о Java, и даже если она будет портирована на подобные экзотические процессоры, я думаю, что спекулятивная запись в память будет зарублена. Во всяком случае, я сомневаюсь, что такая запись в память допускается спецификацией JVM.Спецификация JVM не оперирует такими понятиями, как "спекулятивная запись" в принципе. JVM для корректной работы нужно две вещи: 1) Sequential consistency по умолчанию для одного потока - что бы работали однопоточные программы; 2) Sequential consistency _по_требованию_ для нескольких потоков - что бы работали многопоточные программы. Что здесь интересно? Если будет отсутствовать п.1, то у вас не будет работать не только JVM, но и все остальные современные приложения. Ибо без sequential consistency запрограммировать что-либо можно только в теории, но не практике. А если будет отсутствовать п.2, то у вас не будет работать не только JVM с несколькими потоками, но и все остальные современные приложения. Ибо что из себя представляют понятия, из того же JSR133 Cookbook? Всякие там StoreLoad и иже с ними? Это просто логичесике обертки над какими-то физическими инструкциями процессора и правилами компилятора. Не более того. Если для этих логических оберток нет конкретных решений на конкретной платформе, значит она не предназначена для многопоточной работы в принципе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 15:02 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwaА точно программа это поведение сможет обозреть, если вместе с введением этих оптимизаций идут правки в протоколы конгерентности кэшей и др. ? Просто в противном случае подобная оптимизация может сломать даже корректную программу.Вопрос лишен смысла. Я могу с таким же успехом спросить: "А точно ли текущая модель работы с памятью x86 работает правильно?" Теоретически, она может работать правильно. Работает ли она правильно по факту - не знаю. Так же и со спекулятивными записями. Может ли такой подход работать теоретически? Да, может. Работает ли он корректно в конкретном экземпляре Multiscaler/Levo? Не знаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 15:08 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvschwaА точно программа это поведение сможет обозреть, если вместе с введением этих оптимизаций идут правки в протоколы конгерентности кэшей и др. ? Просто в противном случае подобная оптимизация может сломать даже корректную программу.Вопрос лишен смысла. Я могу с таким же успехом спросить: "А точно ли текущая модель работы с памятью x86 работает правильно?" Теоретически, она может работать правильно. Работает ли она правильно по факту - не знаю. Так же и со спекулятивными записями. Может ли такой подход работать теоретически? Да, может. Работает ли он корректно в конкретном экземпляре Multiscaler/Levo? Не знаю. Этот вопрос лишен смысла только для тех, кто не видит разницы между вычитываем старого значения и выполнением участков кода, которые выполнится никак не могли вообще ибо они используют значение, которые никакими операциями, которые выполнялись в программе получено не было. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 16:59 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
О чем спор, а то я запутался? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 17:05 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
забыл никО чем спор, а то я запутался? О том что реордеринг можно наблюдать далеко не на всех архитектурах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 17:13 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
schwaЭтот вопрос лишен смысла только для тех, кто не видит разницы между вычитываем старого значения и выполнением участков кода, которые выполнится никак не могли вообще ибо они используют значение, которые никакими операциями, которые выполнялись в программе получено не было.Ничего не понял, сформулируйте свой вопрос еще раз. Вот мы спекулятивно предположили, что значение calc() вернет true, и пошли в соответствующий бранч. В этом бранче вы выполняем какие-то операции. Потом мы узнали, что calc() на самом деле вернул false. Окей, мы берем и откатываем те изменения, которые успели нагородить, и заново выполняем код с того момента, когда мы сделали ошибочное предположение. Это не какие-то мои додумки, так работают все современные процессоры, почитайте любой мануал, ключевое слово - "speculative branch prediction". НО! Современные процессоры не допускают спекулятивные записи в кэш. Они спекулятивно меняют значения только в рамках регистров процессора. А те архитектуры, что я указал выше, могут записать спекулятивное значение и в свой кэш, и даже в кэш другого ядра. И это будет работать до тех пора, пока данные изменения можно откатить. А откатить их можно. И с точки зрения sequential consistency в рамках одного потока, абсолютно пофиг, где сейчас находятся спекулятивные (то есть потенциально некорректные) значения - в регистрах, в кэшах, или где-либо еще. Потому я и не могу понять, что вы хотите донести. P.S.: Я надеюсь, что все понимают, что когда я говорю "начал спекулятивно выполнять бранч" != "начал спекулятивно выполнять все инструкции в этом бранче". Спекулятивно можно выполнять только то, что можно откатить. Поэтому, например, никто не будет спекулятивно джампить System.out.println(), так как в случае ошибки мы это не сможем откатить. Спекулятивно выполняются только те инструкции, ущерб от которых конкретный процессор сможет компенсировать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 17:35 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvСпекулятивно можно выполнять только то, что можно откатить. Да там наверное десяток машинных инструкций можно откатить, а Вы размахнулись. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 17:48 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjv, Результата работы этих спекулятивных лоудов и сторов никакая программа обозреть не сможет. И как в случае с обычным спекулятивным выполнением также никому ничего не будет видно*. * - Разве что кто-то может обозреть увеличение сумм в счетах за электричество, но эти люди уже не разработчики программ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 19:04 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvВ десятый раз поторюсь: рассуждать на тему того, что именно может делать какой-то абстрактный процессор в вакууме, это все от лукавого. Мы здесь рассуждаем не об абстрактном процессоре в вакууме, а о JVM. Любая реализация JVM на каком угодно процессоре должна вести себя одинаково. Раз интерпретатор, сделанный по букве спецификации, никогда не записывает мусорные значения в память, которые могут быть замечены другим потоком, то и все остальные реализации не должны этого делать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 19:43 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
rfqЛюбая реализация JVM на каком угодно процессоре должна вести себя одинаково.Кто вам это сказал? Где это написано в спецификации? Они должны вести себя одинаково в рамках JMM. А JMM ничего не говорит ни о реордерингах, ни о кэшах, ни о чем-либо подобном. Она лишь дает набор правил, которым должна следовать JVM. И одно из этих правил, например, гласит: volailte чтение, следующее после volatile записи, гарантированно увидит результат этой записи. То есть, вам дают гарантию, что вы увидите что-то определенное, после того, как предпримете определенные шаги (в данном случае - обеспечите волатильное чтение, которое гарантированно идет после волатильной записи). rfqРаз интерпретатор, сделанный по букве спецификации, никогда не записывает мусорные значения в память, которые могут быть замечены другим потоком, то и все остальные реализации не должны этого делать.Это что еще за глупость? Покажите мне, где в спецификации написано, что "интерпретатор не записывает мусорные значения в память". Можете сслыку на это привести? Думаю нет, так как это плод вашей фантазии, который к реальности отношения не имеет. JMM говорит нам: если один поток записал что-то в переменную, то мы не можем ничего сказать, что увидит другой поток. В спецификации не сказано "вы увидите актуальное значение". В ней не сказано "вы увидите старое значение". В ней сказано: " мы не знаем, что вы там увидите ". Может быть старое значение, может быть новое значение, может быть это будет мусорный результат спекуляции, может это будет мусорный результат неатомарной записи long/double значения, да что угодно это может быть. Мы не даем никаких гарантий. Хотите быть в чем-то уверенными? Тогда вот вам synchronized-with, вот вам исключение в лице final - в этих случаях у вас будут гарантии, что вы увидите ровно то, что должны увидеть. Еще раз, что бы уж точно усвоилось: выбор идет не между "старым" и "актуальным", а между "актуальным" и "не актуальным". А что такое "не актуальное" спецификация не говорит . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 20:29 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
cdtyjvВ ней сказано: " мы не знаем, что вы там увидите ". Может быть старое значение, может быть новое значение, может быть это будет мусорный результат спекуляции, может это будет мусорный результат неатомарной записи long/double значения, да что угодно это может быть. В каком месте это сказано? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 20:47 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
rfqcdtyjvВ ней сказано: " мы не знаем, что вы там увидите ". Может быть старое значение, может быть новое значение, может быть это будет мусорный результат спекуляции, может это будет мусорный результат неатомарной записи long/double значения, да что угодно это может быть. В каком месте это сказано? Там не сказано иное. А гарантируется только то, что указано явно. Реализаторы JVM должны обеспечить выполнение некоторых правил. Остальное- как повезёт. "Переупорядочивание", ещё раз, в основном итог взаимодействия ПРОЦЕССОРОВ. JVM обязана бороться с ним в указанных рамках. В остальных- как 247й транзистор контроллера памяти захотел- так и переупорядочится запись С ТОЧКИ ЗРЕНИЯ соседнего процесса. Одномоментность при взгляде с разных мест разная :) PS: где вы вообще видели интерпретатор JVM? Давно уже компилятор в большинстве случаев работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 22:00 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
rfqcdtyjvВ ней сказано: " мы не знаем, что вы там увидите ". Может быть старое значение, может быть новое значение, может быть это будет мусорный результат спекуляции, может это будет мусорный результат неатомарной записи long/double значения, да что угодно это может быть. В каком месте это сказано?Более глубокое изучение JMM показало следующее: 1) JMM запрещает out-og-thin-air значения даже для некорректно синхронизированных программ. Формально это означает, что если я читаю X, то прочитанное мной значение обязательно должно было быть _честно_ записано туда ранее. Так как спекулятивные записи к _честным_ не относятся, то чтение спекулятивных значений в JMM запрещено. Формально это описано вот в этой главе JLS - http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.8 . А более человеческим языком вот здесь - http://cseweb.ucsd.edu/classes/fa05/cse231/Fish.pdf . 2) При всем при этом, как мы знаем, JMM допускает неатомарные записи long/double. То есть, если у меня был long, иниициализированный нулем, один тред записал туда 0xffffffff00000000, а другой 0x00000000ffffffff, то третий поток может увидеть не три, а четыре значения: 0, 0x00000000ffffffff, 0xffffffff00000000 и 0xffffffffffffffff . Лично я не вижу отличий между тем, что поток увидит какое-то левое значение, из-за того, что две одновременные записи long "наложились" друг на друга, и тем, что поток увидит спекулятивную запись, которая потом будет откачена. А JMM эти два случая разделяет. То есть, неатомарная запись long/double, это по логике вещей вроде бы out-of-thin-air, а вроде бы и нет. Собственно, поэтому я и настаивал на том, что чтение спекулятивной записи не запрещено, ибо я не вижу разницы между этими двумя случаями. Как это понять - хз. Думаю, здесь спасет разве что письмо в concurrency-interest в надежде услышать ответ от отцов-основателей JMM. Что я сегодня и сделаю, а потом напишу ответ на Хабре, ибо жесть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 22:35 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
забыл никО чем спор, а то я запутался? Отличный вопрос. Я бы сказал так: с автором тренингов спорят о том, стоит ли вводить излишние сущности там, где они не нужны. Спор примерно такой: ТС2 * 2 = 4 - это верно только в однопоточной программе, а в многопоточный программе иначе? звезда тренинговКто вам такое сказал? В десятичной системе счисления - да, но вот в троичной совсем иначе! Так что, если вы хотите правильно считать в десятичной системе, учите правила! И потерпите, я скоро буду у вас в городе с циклом лекций по таблице умножения ТСУ меня вроде десятичная... звезда тренинговНу и что? Есть еще, например, двоичная... всеНо у нас же десятичная!! звезда тренинговЭто да, но вот есть еще комплексные числа... всеНо у нас же десятичная!!! звезда тренинговТак-то оно так, но вот в другой галактике... Примерно в таком ключе ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 23:23 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
После тяжелых дум я таки разобрался в вопросе. Итого: 1) Принципиальное отличие между word tearing (т.е. когда мы засрали long/double конкурирующими неатомарными записями) принципиально отличается от гипотетической ошибочной спекулятивной записи тем, что результат word tearing может оставаться актуальным неограниченно долго, а спекулятивная ошибка eventually будет откачена. Таким образом, результат word tearing можно рассматривать, как результат нормального store commit, и его нельзя отнести к out-of-thin-air в том значение, которое использует JMM. 2) Тем не менее, наличие out-of-thin-air результатов не является препятствием для создания рабочих моделей памяти. Пример - модель памяти C++11. Изначально она допускала такое. В 2012 пошли разговоры о том, что бы пойти путем Java, и запретить это ( http://preshing.com/20120625/memory-ordering-at-compile-time/ ). Чем в итоге кончилось - не знаю. 3) Мотивация создателей JMM по запрету out-of-thin-air значений была по сути одна - безопасность. Так как Java ставит security во главу угла (а мы на нее постоянно благополучно кладем. отключая SecurityManager ), ситуация, когда мы можем увидеть какое-то непонятное значение недопустима, так как этим "смотрящим" может быть не-trusted код, а "непонятным значением" может оказаться какой-нибудь пароль. А мы хотим, что бы даже те программисты, которые незнакомы с JMM, могли писать по возможности максимально безопасный код. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 00:52 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Результаты спекулятивного выполнения смогли продержаться невидимыми для программы на протяжении одного сообщения, но потом снова стали видны благодаря какой-то мистической силе JMM. Это уже победа. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 14:08 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
Alexey TominНедавно наткнулся на Ну, Шипилев же. Уже легендарный докладчик. Если понравилось, ищи все его даклады. И на хабре статьи у него клевые. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.02.2014, 11:01 |
|
||
|
Reordering
|
|||
|---|---|---|---|
|
#18+
BlazkowiczAlexey TominНедавно наткнулся на Ну, Шипилев же. Уже легендарный докладчик. Если понравилось, ищи все его даклады. И на хабре статьи у него клевые. Да я знаю- слушал и вживую много раз. Но обычно всё были заковыристые темы, типа "как я провёл лето" "как я сломал JVM нафиг"- а тут именно ликбез "от и до". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.02.2014, 12:53 |
|
||
|
|

start [/forum/topic.php?all=1&fid=59&tid=2127580]: |
0ms |
get settings: |
10ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
202ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
117ms |
get tp. blocked users: |
2ms |
| others: | 245ms |
| total: | 619ms |

| 0 / 0 |
