Читайте тогда условное письмо против записи - PullRequest
6 голосов
/ 04 марта 2010

Что в среднем быстрее - проверьте значение, а затем при необходимости назначьте или просто назначьте? Или, в терминах C ++:

bool b;
if(b)
    b = false;

или

b = false;

Предположим, что условие if () выполняется с вероятностью 50%. Ответ, скорее всего, будет сильно зависеть от архитектуры - пожалуйста, выскажите свои соображения низкого уровня. Запись всегда загрязняет строку кэша - верно? Таким образом, избегая записи, мы избегаем очистки кэша в 0,5 случаев. Но достаточно умный кеш может обнаружить тривиальную запись, а не грязную. Но безусловная запись - это всегда ровно одна операция памяти, а чтение-запись - в среднем 1,5 операции.

Отказ от ответственности: это вопрос любопытства, а не проблема, с которой я на самом деле сталкиваюсь.

Ответы [ 7 ]

4 голосов
/ 04 марта 2010

Ветви дорогие на современных процессорах, а доступ к памяти дорогой на встроенных / старых процессорах. Таким образом, «плоское назначение» всегда будет быстрее, если у вас нет какой-то странной памяти, для написания которой требуется больше времени, чем для чтения (подсказка: нет)

Хуже по этим причинам конкретно:

  • Инструкция ветвления. Это может быть предсказано процессором, но все равно существует вероятность дополнительных затрат.
  • 2 обращения к памяти вместо 1. Чтение и запись в большинстве форм памяти имеют одинаковую скорость, так зачем делать это дважды, если вы можете сделать это один раз?
  • Больше кода. это микро, но для выполнения оператора if необходимо выдать больше инструкций. Это означает, что дополнительная пара считываний из памяти и больше места излишне потребляются в кеше.
  • А для пессимистов это может означать, что компилятор C ++ решает поместить эту переменную в регистр вместо других более необходимых переменных.
  • Также, если вы предполагаете, что b занесен в регистр. Чтение / запись в реестре очень дешевы, но они не бесплатны.
1 голос
/ 04 марта 2010

На современном конвейерном процессоре вы должны принять это во внимание:

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

Чтение с условной записью имеет , по крайней мере, один доступ к памяти и ветвь, которая может ошибочно прогнозироваться. Если предположить, что ветвление заняло 50% времени, у вас в среднем 1,5 обращения к памяти, плюс вероятность ошибочного прогнозирования.

Безусловная запись имеет точно один доступ к памяти и никакой ветви вообще.

Теперь вам нужно сбалансировать стоимость неправильного прогнозирования со стоимостью магазина, которая меняется в зависимости от того, сколько у вас агентов кеша.

1 голос
/ 04 марта 2010

Недавно я читал статьи об очень быстрых методах сжатия, и парни подчеркивали необходимость избегать ветвления if для достижения максимальной производительности. Причиной этому является конвейеризация процессора. Использование if s нарушает многие оптимизации, которые ЦП может выполнять для параллельного выполнения частей кода. Так что, если у вас было много этих операций, возможно, будет быстрее использовать b = false.

1 голос
/ 04 марта 2010

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

1 голос
/ 04 марта 2010

Зависит от разных вещей:

  • насколько предсказуема ветвь (в первом сценарии)
  • находится ли b в регистре
  • какую архитектуру вы используете
1 голос
/ 04 марта 2010

Определенно стоит профилировать это на разных архитектурах, чтобы получить реальные результаты.

0 голосов
/ 04 марта 2010

Если вы делаете присваивание указателя, ссылки или базового типа значения, я лично думаю, что прямое присваивание будет быстрее (желая увидеть результат на профилировщике). В среде с 50% вероятностью вы будете выполнять гораздо больше инструкций, чем внесение значений в реестр. Назначение объекта структуры или класса, который запускает оператор присваивания, будет самым дорогим. Условная логика также вводит больше инструкций и добавляет к метрикам сложности кода

...