Является ли изменяемая переменная «чтение» так же быстро, как нормальное чтение?

Я знаю, что пишуvolatile переменная сбрасывает его из памяти всех процессоров, однако я хочу знать, если чтение в энергозависимую переменную происходит так же быстро, как обычное чтение?

Можноvolatile переменные когда-либо помещаются в кэш процессора или они всегда выбираются из основной памяти?

 pdeva01 июл. 2010 г., 20:58
кажется, сейчас там
 Hans-Peter Störr01 июл. 2010 г., 14:25
Не могли бы вы добавить & quot; java & quot; где то в вопросе? С C возникли путаницы - просто установки ключевого слова недостаточно.

Ответы на вопрос(5)

особенно на многоядерных процессорах (но также и на одноядерных). Исполняющее ядро должно извлечь из фактического адреса памяти, чтобы убедиться, что оно получает текущее значение - переменная действительно не может быть кэширована.

В отличие от одного другого ответа здесь, изменчивые переменныеnot used just for device drivers! Иногда они необходимы для написания высокопроизводительного многопоточного кода!

 21 нояб. 2011 г., 15:24
@bestsss - хорошо, я допускаю незнание деталей, но меня всегда учили, что нормальное чтение «всегда» опережают волатильные чтения. Я не поставил 1 миллиард долларов на ответ.
 14 мар. 2017 г., 21:06
Этот ответ совершенно неверен и предполагает, что фактические процессоры ведут себя так, как их представляют теоретические. Да, мы представляем, что фактическое ядро должно извлекать данные из фактического адреса памяти, чтобы убедиться, что оно получает текущее значение, но реальные процессоры этого не делают. У них естьmuch более эффективные способы достижения того же результата, например, принуждение записей с других процессоров к недействительности их строк кэша, а не кеширование.
 21 нояб. 2011 г., 16:14
Нет, некоторым процессорам может потребоваться барьер нагрузки-нагрузки, но он все еще дешев. Как правило большого пальца считают летучие чтения просто нормальными нагрузками. Если какой-либо процессор должен перейти в основную память (он же промах кеша), это ужасный недостаток дизайна.
 21 нояб. 2011 г., 15:16
Volatile reads cannot be as quick, especially on multi-core CPUs это совершенно не соответствует действительности, на большинстве аппаратных средств энергозависимые чтения представляют собой обычные нагрузки. Загрузка обходится дорого, когда отсутствует кеш, но энергозависимые чтения не попадают в основную память, если в кеше есть значение, и даже энергозависимые записи (которые стоят дорого) могут обновить строки локального кэша ЦП. Многопроцессорность / сокет зависит от протокола когерентности кэша для обеспечения допустимых значений, но от того, что он не делает энергозависимые чтения в любом месте более дорогими.

http://brooker.co.za/blog/2012/09/10/volatile.html, В статье блога утверждается, что энергозависимые чтения могут быть намного медленнее (также для x86), чем энергонезависимые чтения на x86.

Test 1 is a parallel read and write to a non-volatile variable. There is no visibility mechanism and the results of the reads are potentially stale. Test 2 is a parallel read and write to a volatile variable. This does not address the OP's question specifically. However worth noting that a contended volatile can be very slow. Test 3 is a read to a volatile in a tight loop. Demonstrated is that the semantics of what it means to be volatile indicate that the value can change with each loop iteration. Thus the JVM can not optimize the read and hoist it out of the loop. In Test 1, it is likely the value was read and stored once, thus there is no actual "read" occurring.

Marc Booker's tests

Благодарим Марка Букера за проведение этих тестов.

 pdeva19 нояб. 2012 г., 10:37
это, кажется, имеет место только тогда, когда утверждается изменчивое.
 30 мая 2013 г., 15:22
@pdeva, нет, на графике ясно видно, что неконтролируемые энергозависимые чтения медленнее, чем энергонезависимые. Глазное, оно выглядит в 2-3 раза медленнее.

ных накладных расходов, связанных, в частности, с изменчивым чтением, хотя есть последствия для других оптимизаций.

Поваренная книга JMM от Дуга Ли, см. Таблицу архитектуры внизу.

Чтобы уточнить: нет никаких дополнительных издержек, связанных с самим чтением. Барьеры памяти используются для обеспечения правильного порядка. JSR-133 классифицирует четыре барьера «LoadLoad, LoadStore, StoreLoad и StoreStore». В зависимости от архитектуры некоторые из этих барьеров соответствуют «бездействию», то есть никаких действий не предпринимается, другие требуют ограждения. Там нет никаких неявных затрат, связанных с самой нагрузкой, хотя они могут быть понесены, если забор на месте. В случае x86, только барьер StoreLoad приводит к забору.

Как указано в сообщении в блоге, тот факт, что переменная является изменчивой, означает, что существуют предположения о природе переменной, которые больше не могут быть сделаны, и некоторые оптимизации компилятора не будут применены к изменчивой.

Летучие - это не то, что следует использовать с умом, но их также не следует опасаться. Есть много случаев, когда вместо более сильного запирания достаточно летучего.

 07 июл. 2009 г., 06:49
Как это может быть? А как насчет многоядерных процессоров? (Не читая всю ссылку вы разместили)
 08 июл. 2013 г., 23:41
Правильный. Тем не менее, это семантика оптимизации, которая лежит вне тех, которые явно налагаются volatile. Основным ответом на этот вопрос является «Это зависит от архитектуры». Пока комментарии верны. Многие люди боятся нестабильности, и это несколько глупо. Хотя я также не рекомендовал бы все время использовать volatile.
 08 июл. 2013 г., 22:55
Ничто не может быть «бездействующим», если только оно не может быть полностью удалено из вашей программы. Энергозависимые операции чтения дешевы, но не бесплатны и препятствуют оптимизации так, как это делают обычные операции чтения (например, энергозависимые операции чтения не могут быть выведены из циклов или считаны из регистра). «Нет операции» в этом случае относится к отсутствию соответствующей инструкции забора, но само чтение имеет семантику, и те имеют стоимость.

volatile он говорит компилятору не оптимизировать эту переменную. Это вынуждает большинство операций рассматривать состояние переменной как неизвестное. Поскольку это изменчиво, это могло быть изменено другим потоком или некоторой другой аппаратной операцией. Таким образом, для чтения потребуется перечитать переменную, и операции будут иметь вид чтения-изменения-записи.

Этот тип переменной используется для драйверов устройств, а также для синхронизации с мьютексами / семафорами в памяти.

 07 июл. 2009 г., 07:39
Не актуально, вопрос к Java.
 26 авг. 2010 г., 15:29
@ ripper234: Я сыт по горло этими людьми, занижая рейтинг, когда он на 100% жизнеспособен. Приведенный выше ответ абсолютно верен во всех отношениях, даже для Java! Ripper234, я советую переоценить свой комментарий и понизить рейтинг!
 07 июл. 2009 г., 08:36
Это означает что-то немного другое в Java.
 07 июл. 2009 г., 07:40
Это по-прежнему актуально, если вы понимаете, что означает волатильность.

что компилятор не может оптимизировать переменную, поместив ее значение в регистр процессора. Он должен быть доступен из основной памяти. Однако он может быть помещен в кэш процессора. Кэш гарантирует согласованность между любыми другими процессорами / ядрами в системе. Если память сопоставлена с IO, то все немного сложнее. Если оно было разработано как таковое, аппаратное обеспечение предотвратит кэширование этого адресного пространства, и все обращения к этой памяти перейдут на аппаратное обеспечение. Если такой конструкции нет, разработчикам аппаратного обеспечения могут потребоваться дополнительные инструкции процессора, чтобы гарантировать, что чтение / запись проходит через кеши и т. Д.

Как правило, «летучий» Ключевое слово используется только для драйверов устройств в операционных системах.

 07 июл. 2009 г., 06:55
Вот статья доктора Добба, в которой более подробно рассматриваются различия:ddj.com/hpc-high-performance-computing/212701484
 16 нояб. 2017 г., 10:56
Я не знаю, почему за этот ответ проголосовали, но изменчивое ключевое слово в Java обеспечивает ту же функциональность. По сути, переменная не кэшируется, не записывается и не считывается из памяти, поэтому изменения видны каждому потоку.
 07 июл. 2009 г., 22:47
Читатель не сказал java и конкретно упомянул кэш 2-го уровня, поэтому я предположил наиболее распространенный сценарий ... C.
 07 июл. 2009 г., 06:39
Это может быть то, что volatile означает в C, но это не то, что оно означает в Java. В Java изменчивость связана с тем, будет ли один поток, выполняющий чтение, «видеть» изменения, сделанные другим потоком. Это больше, чем просто, может ли значение быть в регистре ЦП. Ключевое слово volatile также предотвращает возможные изменения порядка JVM в коде, использующем переменную.

Ваш ответ на вопрос