Здравствуйте, subdmitry, Вы писали:
S>Здравствуйте, diamond666, Вы писали:
D>>как нету, только что скачал — все есть Loads May Be Reordered with Earlier Stores to Different Locations, вот даже скиншот с текстом приатачил (там защита, не скопипируешь).
S>Странно, у меня оно выглядит так:
S>http://i39.tinypic.com/33w7jac.png
S>>>А что там, собственно, написано, нельзя ли это в кратце написать?
S>Спасибо, понял. Выходит, этот код прямо по интелловскому мануалу и написан. Типа проверка, кто читал этот мануал и знает.
Покапавшись детально тут,тут и тут, я пришел к выводу что это не out of order execution, а типа назовем "delayed store", у каждого процессора есть свой малюсенький store buffer в который он кладет записанные новые значение переменных, потом он должен скинуть их в свой кеш L1, работает этот store buffer как раз по правилам той Intel'овской доки. Так вот в нашем случае операции выполняются последовательно, но mov [AA],1 записывается не в кеш а в этот буфер, а потом происходит чтение и другая запись, и только потом сброс store buffer, это объясняет почему 0 появляются не в 1 месте, а иногда в нескольких. Т.к. эти store buffer'ы не когерентны между процессорами происходят вот такие "пирожки". Там кстати рассматривается и более сложный случай "intra-processor forwarding".
только встает тогда вопрос почему из spin-lock'ов выходят через обычный mov (входят соответственно через lock bts/xchg), получается значаение в другом процессоре n-ое кол-во тактов остается устаревшим, пока не скинется store buffer 1 процесора, я имею ввиду test-test-and-set алгоритмы.
Сильно не пинайте, голова болит от всей это неопределенности, могу очень ошибаться в своих рассуждениях.
Здравствуйте, diamond666, Вы писали:
D>Так вот в нашем случае операции выполняются последовательно, но mov [AA],1 записывается не в кеш а в этот буфер, а потом происходит чтение и другая запись, и только потом сброс store buffer, это объясняет почему 0 появляются не в 1 месте, а иногда в нескольких. Т.к. эти store buffer'ы не когерентны между процессорами происходят вот такие "пирожки". Там кстати рассматривается и более сложный случай "intra-processor forwarding".
Интересно. И на сколько тактов получается задержка сброса данных, где-нибудь написано?
And if you listen very hard the alg will come to you at last.
Здравствуйте, subdmitry, Вы писали:
S>Если мы все поняли, объясните мне, почему на хабре, где пробовали запускать эту программу, сообщают о несрабатывании бинго в где-то 20-30% случаев.
Ты когда кубик бросаешь всегда шестёрку выкидываешь? Или другие варианты тоже встречаются? В том то весь смысл, что в рассматриваемом случае уже на уровне процессора не гарантируется порядок выполнения команд. "Не гарантируется" — это означает, что процессор может перетасовать выполнение инструкций, а может и оставить. Для того, чтобы не зависеть от такого поведения используют синхронизацию (только нормальную, а не ту, что в примере).
Именно поэтому я сразу и сказал, что преподносить эту задачу для которой, цитирую : "требуются глубокие знания языка C++, принципов работы компиляторов" является полным бредом.
Этим метаквотерам матчасть сначала изучить не помешало бы.
Здравствуйте, realloc, Вы писали:
S>>Если мы все поняли, объясните мне, почему на хабре, где пробовали запускать эту программу, сообщают о несрабатывании бинго в где-то 20-30% случаев.
R>Ты когда кубик бросаешь всегда шестёрку выкидываешь? Или другие варианты тоже встречаются? В том то весь смысл, что в рассматриваемом случае уже на уровне процессора не гарантируется порядок выполнения команд. "Не гарантируется" — это означает, что процессор может перетасовать выполнение инструкций, а может и оставить.
Прикол, однако состоит в том, что кубик бросается много раз — циклы-то крутятся. Причем в их работу периодически вмешивается ОС, выполняя другие процессы. Казалось бы, идеальные условия для того, чтобы шестерка в конце концов выпала.
Мне в голову приходит только такое объяснение, что Винда не всегда назначает потокам разные ядра. Хм.
And if you listen very hard the alg will come to you at last.
Здравствуйте, subdmitry, Вы писали:
S>Здравствуйте, realloc, Вы писали:
S>>>Если мы все поняли, объясните мне, почему на хабре, где пробовали запускать эту программу, сообщают о несрабатывании бинго в где-то 20-30% случаев.
R>>Ты когда кубик бросаешь всегда шестёрку выкидываешь? Или другие варианты тоже встречаются? В том то весь смысл, что в рассматриваемом случае уже на уровне процессора не гарантируется порядок выполнения команд. "Не гарантируется" — это означает, что процессор может перетасовать выполнение инструкций, а может и оставить.
S>Прикол, однако состоит в том, что кубик бросается много раз — циклы-то крутятся. Причем в их работу периодически вмешивается ОС, выполняя другие процессы. Казалось бы, идеальные условия для того, чтобы шестерка в конце концов выпала.
S>Мне в голову приходит только такое объяснение, что Винда не всегда назначает потокам разные ядра. Хм.
Конечно не всегда. Она может тебя прямо посередине цикла зашедулить на другое ядро, если не предпринимать ничего специального чтобы этого не было. И все современные юникса так же себя ведут.
Здравствуйте, realloc, Вы писали:
R>Здравствуйте, subdmitry, Вы писали:
S>>Здравствуйте, realloc, Вы писали:
S>>>>Если мы все поняли, объясните мне, почему на хабре, где пробовали запускать эту программу, сообщают о несрабатывании бинго в где-то 20-30% случаев.
R>>>Ты когда кубик бросаешь всегда шестёрку выкидываешь? Или другие варианты тоже встречаются? В том то весь смысл, что в рассматриваемом случае уже на уровне процессора не гарантируется порядок выполнения команд. "Не гарантируется" — это означает, что процессор может перетасовать выполнение инструкций, а может и оставить.
S>>Прикол, однако состоит в том, что кубик бросается много раз — циклы-то крутятся. Причем в их работу периодически вмешивается ОС, выполняя другие процессы. Казалось бы, идеальные условия для того, чтобы шестерка в конце концов выпала.
S>>Мне в голову приходит только такое объяснение, что Винда не всегда назначает потокам разные ядра. Хм.
R>Конечно не всегда. Она может тебя прямо посередине цикла зашедулить на другое ядро, если не предпринимать ничего специального чтобы этого не было. И все современные юникса так же себя ведут.
Или наоборот: программа может месяцами на одном ядре крутиться, если операционке так надо.
Здравствуйте, realloc, Вы писали:
S>>Мне в голову приходит только такое объяснение, что Винда не всегда назначает потокам разные ядра. Хм. R>Конечно не всегда. Она может тебя прямо посередине цикла зашедулить на другое ядро, если не предпринимать ничего специального чтобы этого не было. И все современные юникса так же себя ведут.
Все-таки правильно было бы в ситуации, когда других особых потребителей вычислительных мощностей нет, выдавать двум этим процессам разные ядра в почти нераздельное пользование. То есть это или еще одна вещь в Виндах, которая сделана неправильно, или у ребят что-то крутилось еще кроме этого приложения, или мы чего-то не понимаем.
And if you listen very hard the alg will come to you at last.
Здравствуйте, subdmitry, Вы писали:
S>Здравствуйте, diamond666, Вы писали:
D>>Так вот в нашем случае операции выполняются последовательно, но mov [AA],1 записывается не в кеш а в этот буфер, а потом происходит чтение и другая запись, и только потом сброс store buffer, это объясняет почему 0 появляются не в 1 месте, а иногда в нескольких. Т.к. эти store buffer'ы не когерентны между процессорами происходят вот такие "пирожки". Там кстати рассматривается и более сложный случай "intra-processor forwarding".
S>Интересно. И на сколько тактов получается задержка сброса данных, где-нибудь написано?
А хз, нигде ничего вменяемого нет, только упоминания в разных блогах и в доках AMD, может там связанно с этим store buffer, может процессор раскидал все на разные execution unit'ы и начал выполнять паралельно, может вообще произвел чтение раньше записи, я уже забил получить точный ответ.
Короче если есть чтение после записи которое каким то образом зависит от этой запси — готовься к проблемам, поэтому во всяких .NET, Java при присовоениях используеют разные симантики обращения, в конечном итого совдятся к memory barier'ам.
В данном конкретном случае если вставить вот такое, Bingo мы никогда не увидим: