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

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

206
задан Evan Teran 23 July 2012 в 02:33
поделиться

12 ответов

volatile необходим, если Вы читаете из места в памяти, в которую, скажем, может записать абсолютно отдельный process/device/whatever.

я раньше работал с двухпортовым поршнем в многопроцессорной системе в прямом C. Мы использовали аппаратные средства, управляемые 16 битовых значений как семафор для знания, когда другой парень был сделан. По существу мы сделали это:

void waitForSemaphore()
{
   volatile uint16_t* semPtr = WELL_KNOWN_SEM_ADDR;/*well known address to my semaphore*/
   while ((*semPtr) != IS_OK_FOR_ME_TO_PROCEED);
}

Без volatile, оптимизатор рассматривает цикл как бесполезный (Парень никогда не устанавливает значение! Он гаек, избавьтесь от того кода!) и мой код продолжился бы не получив семафор, вызвав проблемы позже.

253
ответ дан Flexo 23 November 2019 в 04:46
поделиться

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

, Например, я работал над встроенной платформой, был компилятор, делал некоторый неправильный assuptions относительно значения переменной. Если бы код не был оптимизирован, то программа работала бы хорошо. С оптимизацией (которые были действительно необходимы, потому что это была критическая стандартная программа) код не будет работать правильно. Единственное решение (хотя не очень корректный) состояло в том, чтобы объявить 'дефектную' переменную как энергозависимую.

2
ответ дан INS 23 November 2019 в 04:46
поделиться
  1. необходимо ли использовать его для реализации спин-блокировок, а также некоторых (все?) структуры данных без блокировок
  2. использование это с атомарными операциями/инструкциями
  3. помогло мне однажды преодолеть ошибку компилятора (неправильно сгенерированный код во время оптимизации)
6
ответ дан Mladen Janković 23 November 2019 в 04:46
поделиться

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

7
ответ дан indentation 23 November 2019 в 04:46
поделиться

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

template <typename T> 
class Foo {
  std::enable_if_t<sizeof(T)==4, void> f(T& t) 
  { std::cout << 1 << t; }
  void f(T volatile& t) 
  { std::cout << 2 << const_cast<T&>(t); }

  void bar() { T t; f(t); }
};

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

Примечание, что код никогда на самом деле зависит от volatile доступ к памяти.

7
ответ дан MSalters 23 November 2019 в 04:46
поделиться

Крупное приложение, что я раньше продолжал работать в начале 1990-х, содержало обработку исключений на базе С с помощью setjmp и longjmp. Энергозависимое ключевое слово было необходимо на переменных, значения которых должны были быть сохранены в блоке кода, который служил пунктом "выгоды", чтобы они Вар быть сохраненным в регистрах и вытертым longjmp.

10
ответ дан 23 November 2019 в 04:46
поделиться

НЕОБХОДИМО использовать энергозависимый при реализации структур данных без блокировок. Иначе компилятор является бесплатным оптимизировать доступ к переменной, которая изменит семантику.

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

, Например, это - то, как InterlockedIncrement объявляется в API Win32:

LONG __cdecl InterlockedIncrement(
  __inout  LONG volatile *Addend
);
23
ответ дан Frederik Slijkerman 23 November 2019 в 04:46
поделиться

От "Энергозависимый как обещание" статья Dan Saks:

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

Вот ссылки на три из его статей относительно volatile ключевое слово:

45
ответ дан AkaZecik 23 November 2019 в 04:46
поделиться

Некоторые процессоры имеют регистры с плавающей точкой, которые имеют больше чем 64 бита точности (например, 32-разрядный x86 без SSE, см. комментарий Peter). Тот путь при выполнении нескольких операций на числах двойной точности, Вы на самом деле получает ответ более высокой точности, чем если бы необходимо было усечь каждый промежуточный результат к 64 битам.

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

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

68
ответ дан tfinniga 23 November 2019 в 04:46
поделиться

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

79
ответ дан ChrisN 23 November 2019 в 04:46
поделиться

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

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

7
ответ дан 23 November 2019 в 04:46
поделиться

Другие ответы уже упоминают, что избежали некоторой оптимизации чтобы к:

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

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

А энергозависимое чтение похоже на входную операцию (как scanf или использование cin): значение, кажется, прибывает из за пределами программы, таким образом, любое вычисление, которое имеет зависимость от значения, должно запуститься после него .

А энергозависимая запись похожа на выходную операцию (как printf или использование cout): значение, кажется, передается за пределами программы, поэтому если значение зависит от вычисления, это должно быть закончено прежде .

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

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

0
ответ дан 23 November 2019 в 04:46
поделиться
Другие вопросы по тегам:

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