Почему энергозависимый недостаточно?

В вашем коде есть две ошибки:

  1. Столбец данных purchase_month не является объектом класса "Date".
  2. Вам нужно group данные по type.

Я имею в виду следующее.

sample_data$purchase_month <- as.Date(paste(sample_data$purchase_month, "01", sep = "-"))

ggplot(data = sample_data, 
       aes(x = purchase_month, y = orders, color = type), group = type) + 
  geom_line(size = 1) +
  scale_color_manual(values = c("#00AFBB", "#E7B800")) +
  theme_minimal()

enter image description here

9
задан Community 23 May 2017 в 12:33
поделиться

7 ответов

Herb Sutter недавно написал статью о volatile и что это действительно означает (как это влияет на упорядочивание доступа к памяти и атомарности) в собственном C++..NET и среды Java. Это - довольно хорошее чтение:

10
ответ дан 4 December 2019 в 10:05
поделиться

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

0
ответ дан 4 December 2019 в 10:05
поделиться

энергозависимый в.NET действительно делает доступ к переменной атомарным.

Проблема, это достаточно часто. Что, если необходимо считать переменную, и если это 0 (указание, что ресурс является бесплатным), Вы устанавливаете его на 1 (указание, что это заблокировано, и другие потоки должны избегать его).

Чтение этого 0 является атомарным. Запись этого 1 является атомарной. Но между теми двумя операциями, что-либо могло бы произойти. Вы могли бы считать 0, и затем прежде чем можно будет записать этот 1, другой поток вскакивает, читает этот 0 и пишет 1.

Однако энергозависимый в.NET действительно гарантирует атомарность доступов к переменной. Это просто не гарантирует потокобезопасности для операций, полагающихся на множественные доступы к нему. (Правовая оговорка: энергозависимый в C/C++ даже не гарантирует это. Именно так Вы знаете. Это намного более слабо, и occasinoally источник ошибок, потому что люди предполагают, что это гарантирует атомарность :))

Таким образом, необходимо использовать блокировки также, для группирований нескольких операций как одного ориентированного на многопотоковое исполнение блока. (Или, для простых операций, Interlocked операции в.NET могут добиться цели),

6
ответ дан 4 December 2019 в 10:05
поделиться

Я мог бы забегать вперед здесь, но это звучит мне, как будто Вы путаете две проблемы здесь.

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

Другой энергозависимость, когда это значение, которое, как ожидают, изменится, и почему.

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

Однако второй выпуск, даже когда Вы делаете вещь блокировки, что будет другие потоки видеть.

A volatile поле в.NET является полем, которое знает компилятор, может измениться в произвольные моменты времени. В однопоточном мире замена переменной - что-то, что происходит в какой-то момент в последовательном потоке инструкций, таким образом, компилятор знает, когда это добавило код, который изменяет его, или по крайней мере когда это обратилось к внешнему миру, который может или не мог изменить его так, чтобы, после того как код возвратился, это не могло бы быть то же значение, которым это было перед вызовом.

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

С многопоточностью однако, которая могла бы дать Вам некоторые проблемы. Один поток, возможно, скорректировал значение, и другой поток, из-за оптимизации, не будет читать это значение в течение некоторого времени, потому что это знает, что не изменилось.

Таким образом, когда Вы отмечаете поле как volatile Вы в основном говорите компилятору, что он не должен предполагать, что имеет текущее значение этого в любой точке, за исключением захвата снимков каждый раз, когда ему нужно значение.

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

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

Например, если Вы будете на 32-разрядном CPU и записи 64-разрядного значения, то та операция записи потребует, чтобы два шага завершились, и если другому потоку на другом CPU удастся считать 64-разрядное значение, прежде чем шаг 2 завершился, это получит половину предыдущего значения и половину нового, приятно смешанного, который может быть еще хуже, чем получение устаревшего.


Править: Ответить на комментарий, это volatile гарантирует атомарность операции чтения-записи, это хорошо, верно, в некотором смысле, потому что volatile ключевое слово не может быть применено к полям, которые являются более крупными, чем 32-разрядный, в действительности делая полевое чтение единственной инструкции CPU / записываемый и на 32 и на 64-разрядный CPU. И да, это будет препятствовать тому, чтобы значение было сохранено в регистре как можно больше.

Таким образом, часть комментария является неправильной, volatile не может быть применен к 64-разрядным значениям.

Отметьте также это volatile имеет некоторую семантику относительно переупорядочения чтений/записей.

Для релевантной информации см. документацию MSDN или спецификацию C#, найденную здесь, разделите 10.5.3.

5
ответ дан 4 December 2019 в 10:05
поделиться

На аппаратном уровне несколько центральных процессоров никогда не могут писать одновременно в то же атомарное местоположение RAM. Размер атомарной операции чтения-записи dependeds на архитектуре ЦП, но обычно 1, 2 или 4 байта на 32-разрядной архитектуре. Однако, при попытке читать результат назад всегда существует шанс, что другой ЦП сделал запись к тому же промежутку местоположения RAM. На низком уровне спин-блокировки обычно используются для синхронизации доступа к общей памяти. На высокоуровневом языке такие механизмы можно назвать, например, критические регионы.

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

1
ответ дан 4 December 2019 в 10:05
поделиться

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

Править: разъясниться, энергозависимый никогда не достаточно, если Вы хотите гарантировать атомарность. Или скорее это до компилятора для создания его достаточно или нет.

-1
ответ дан 4 December 2019 в 10:05
поделиться

Проблема входит с базирующимися обмененными на деньги копиями регистра значений Вашей переменной.

При чтении значения CPU увидит в первый раз, если это будет в регистре (быстро) прежде, чем проверить оперативную память (медленнее).

Энергозависимый говорит компилятору выставлять значение к оперативной памяти как можно скорее а не доверять кэшируемому значению регистра. Это только полезно в определенных случаях.

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

Самая безопасная и самая надежная ставка должна заблокировать () (если Вы не можете сделать Взаимно блокируемого.*)

Править: Записи и чтения являются атомарными, если они находятся в блокировке или взаимно блокируемом.* оператор. Энергозависимый один недостаточно в соответствии с Вашим вопросом

0
ответ дан 4 December 2019 в 10:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: