Здравствуйте, dsalodki, Вы писали:
D>Поясните пожалуйста самым простым способом, я гуглю, но что-то не понятно. Толи это позволяет отменить кеширование переменно, толи ещё что-то
Здравствуйте, dsalodki, Вы писали:
D>Поясните пожалуйста самым простым способом, я гуглю, но что-то не понятно. Толи это позволяет отменить кеширование переменно, толи ещё что-то
Это инструкция, запрещающая перенос инструкций через себя при переупорядочивании.
Здравствуйте, dsalodki, Вы писали:
D>Поясните пожалуйста самым простым способом, я гуглю, но что-то не понятно. Толи это позволяет отменить кеширование переменно, толи ещё что-то
Вот смотри, ты пишешь:
a = 5;
b = 10;
И рассчитываешь, что если в b уже 10, то в a точно 5.
Однако процессор может, по разным причинам, исполнить эти команды в другом порядке. В частности потому, что доступ в память, он не так уж и просто устроен, до одних мест может оказаться в данный момент быстрее дотянуться, до других — наоборот.
Причем в пределах простого линейного кода это все будет незаметно, процессор сам позаботится о том, чтобы все выстроить в нужном порядке, создав иллюзию, что с памятью все ОК. А вот если на другом ядре, в другом потоке исполняется код, который тоже пользуется этими переменнымы, то эти два ядра могут промеж собой и не договориться.
Вот тут-то и нужны явные барьеры памяти, чтобы сказать процессору, "доделай, пожалуйста, все операции с памятью, которые я заказывал до этого места, потому что дальше логика моей программы будет рассчитывать на то, что все отложенные/параллельные операции к этому месту уже доделаны"
Pzz>Вот тут-то и нужны явные барьеры памяти, чтобы сказать процессору, "доделай, пожалуйста, все операции с памятью, которые я заказывал до этого места, потому что дальше логика моей программы будет рассчитывать на то, что все отложенные/параллельные операции к этому месту уже доделаны"
На пальцах вроде всё понятно, но вот в те же плюсики завезли чуть ли не штук пять различных типов барьеров. Я пока плотно вопрос не изучал, но по диагонали — нифига не понял, чем отличаются
Здравствуйте, Marty, Вы писали:
M>На пальцах вроде всё понятно, но вот в те же плюсики завезли чуть ли не штук пять различных типов барьеров. Я пока плотно вопрос не изучал, но по диагонали — нифига не понял, чем отличаются
Ну, я описал самый простой случай полного барьера, который полностью отделяет операции "до барьера" от операций "после барьера". Он очень дорогой, и в реальной жизни обычно столько не нужно. Нам, например, может быть важно, чтобы все записи, которые по тексту программы стоят до барьера, до него и произошли, а что там с чтениями, может быть и не важно. Кроме того, у разных процессоров разная модель памяти, а стандарт C++, он, типа, всехний. Поэтому пытается покрыть все возможные варианты. На каком-то конкретном железе разные варианты могут и совпадать, но это не значит, что они будут совпадать на другом железе.
Здравствуйте, Pzz, Вы писали:
Pzz>Вот тут-то и нужны явные барьеры памяти, чтобы сказать процессору, "доделай, пожалуйста, все операции с памятью, которые я заказывал до этого места, потому что дальше логика моей программы будет рассчитывать на то, что все отложенные/параллельные операции к этому месту уже доделаны"
А что они физически представляют? Функцию, инструкцию процессора или что?
Здравствуйте, Pauel, Вы писали:
P>Здравствуйте, Pzz, Вы писали:
Pzz>>Вот тут-то и нужны явные барьеры памяти, чтобы сказать процессору, "доделай, пожалуйста, все операции с памятью, которые я заказывал до этого места, потому что дальше логика моей программы будет рассчитывать на то, что все отложенные/параллельные операции к этому месту уже доделаны"
P>А что они физически представляют? Функцию, инструкцию процессора или что?
a=10
b=5
но a + b = любое число? или вовсе не инициализировано?
Здравствуйте, Pauel, Вы писали:
Pzz>>Вот тут-то и нужны явные барьеры памяти, чтобы сказать процессору, "доделай, пожалуйста, все операции с памятью, которые я заказывал до этого места, потому что дальше логика моей программы будет рассчитывать на то, что все отложенные/параллельные операции к этому месту уже доделаны"
P>А что они физически представляют? Функцию, инструкцию процессора или что?
В Си — функцию. Которая, фактически, превращается в инструкцию процессора.
Здравствуйте, Marty, Вы писали:
M>На пальцах вроде всё понятно, но вот в те же плюсики завезли чуть ли не штук пять различных типов барьеров. Я пока плотно вопрос не изучал, но по диагонали — нифига не понял, чем отличаются
Разные типы барьеров используется для достижения дополнительных выигрышей в производительности. Самый базовый тип — это полный барьер (на чтение и на запись), его используют всегда по-умолчанию. Но если у разработчика есть достаточная необходимость и квалификация, то он может выбирать и более легкие подтипы барьера для конкретных задач где это уместно.
Каждый конкретный язык/среда предоставляет свой набор примитивов для барьеров, поэтому их API могут отличатся, но базовый принцип один и тот же.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, dsalodki, Вы писали:
D>>Поясните пожалуйста самым простым способом, я гуглю, но что-то не понятно. Толи это позволяет отменить кеширование переменно, толи ещё что-то S>Это инструкция, запрещающая перенос инструкций через себя при переупорядочивании.
Это вроде volatile делает, а барьер на уровне железа просит закоммитить все возможные
изменения в памяти и привести кэши в порядок. Просто инструкции может перенести компилятор и
volatile ему это не даст.
Здравствуйте, Sharov, Вы писали:
S>Это вроде volatile делает, а барьер на уровне железа просит закоммитить все возможные S>изменения в памяти и привести кэши в порядок. Просто инструкции может перенести компилятор и S>volatile ему это не даст.
ЕМНИП volatile — один из частных видов барьера памяти.
Здравствуйте, Codealot, Вы писали:
S>>Это вроде volatile делает, а барьер на уровне железа просит закоммитить все возможные S>>изменения в памяти и привести кэши в порядок. Просто инструкции может перенести компилятор и S>>volatile ему это не даст. C>ЕМНИП volatile — один из частных видов барьера памяти.
Скорее способ сказать компилятору, чтобы он не занимался соотв. оптимизациями с соотв.
переменной. Ну и вроде соотв. доп. инструкции барьеров генерятся, хотя для х86 вроде бы
особого смысл они не имеют. Тут в тему должен ворваться netch80 и все объяснить.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Здравствуйте, dsalodki, Вы писали:
D>>>Поясните пожалуйста самым простым способом, я гуглю, но что-то не понятно. Толи это позволяет отменить кеширование переменно, толи ещё что-то S>>Это инструкция, запрещающая перенос инструкций через себя при переупорядочивании.
S>Это вроде volatile делает, а барьер на уровне железа просит закоммитить все возможные S>изменения в памяти и привести кэши в порядок. Просто инструкции может перенести компилятор и S>volatile ему это не даст.
volatile как модификатор переменной — запрет на кэширование. volatile как инструкция — запрет на чтение/запись из кэша в конкретном месте, т.е. немного не о том в общем случае, но в частном (C# и .NET) volatile фактически генерирует вокруг обращений еще и барьеры. В языках, где volatile не генерирует барьеры, проще представить одно без другого.
Барьер же — это идея, а не команда кэшам, которую они выполняют. Идея о том, что порядок операций должен быть вот такой, меняться он может "так" и "этак", но не "вот так", и эффекты от этих операций "ощутимы вот таким образом". А железо, в свою очередь (даже не само железо, а модель памяти, скорее), должно соответствовать и обеспечивать корректную работу этой идеи. Если для этого требуется сбросить кэши — будет исполнено. Если потребуется затормозить ядро — будет так.