Википедия, один из истинных источников знаний, гласит:
На большинстве старых микропроцессоров побитовые операции выполняются несколько быстрее, чем операции сложения и вычитания, и обычно значительно быстрее, чем операции умножения и деления. На современных архитектурах это не так: побитовые операции, как правило, имеют ту же скорость, что и добавление (хотя и быстрее, чем умножение).
Есть ли практическая причина для изучения поразрядных хаков, или теперь это то, чему вы научились для теории и любопытства?
Поразрядные операции заслуживают изучения, потому что у них много приложений. Нецелесообразно заменять арифметические операции. Криптография, компьютерная графика, хеш-функции, алгоритмы сжатия и сетевые протоколы – вот лишь некоторые примеры, когда побитовые операции чрезвычайно полезны.
Строки, которые вы цитировали в статье в Википедии, просто попытались дать некоторые подсказки о скорости побитовых операций. К сожалению, в статье не приводятся хорошие примеры приложений.
Побитовые операции по-прежнему полезны. Например, они могут использоваться для создания «флагов» с использованием одной переменной и сохранения количества переменных, которые вы использовали бы для обозначения различных условий. Что касается производительности при арифметических операциях, лучше оставить компилятор оптимизацией (если вы не какой-то гуру).
Они полезны для понимания того, как работает двоичный код; в противном случае нет. На самом деле, я бы сказал, что даже если побитовые хаки быстрее в данной архитектуре, это задача компилятора использовать этот факт – а не ваш. Напишите, что вы имеете в виду.
Конечно (мне), ответ – да. Тот факт, что в настоящее время команда add
работает так же быстро, как и or
или а, and
просто означает, что … но or
не является add
и вы будете использовать его, когда вам нужно все равно (не для того, чтобы суммировать, но просто для выполнения or
, …). Улучшения в скорости инструкций, таких как добавление, деление и т. Д., Просто означают, что теперь вы можете использовать их и меньше беспокоиться о влиянии на производительность, но теперь это правда, как и в прошлом, что вы не измените ни одного add
на несколько поразрядных операция!
Единственный случай, когда имеет смысл использовать их, – это то, что вы фактически используете свои числа в качестве битрейдеров. Например, если вы моделируете какое-то оборудование, а переменные представляют собой регистры.
Если вы хотите выполнить арифметику, используйте арифметические операторы.
Зависит от вашей проблемы. Если вы контролируете аппаратное обеспечение, вам нужны способы установить одиночные биты в целое число.
Купите плату PCI OGD1 (открытую графическую карту) и поговорите с ней, используя libpci. http://en.wikipedia.org/wiki/Open_Graphics_Project
Это правда, что в большинстве случаев, когда вы умножаете целое число на константу, которая является степенью двух, компилятор оптимизирует ее для использования бит-сдвига. Однако, когда сдвиг также является переменной, компилятор не может вычесть его, если вы явно не используете операцию сдвига.
Смешной никто не счел нужным упомянуть массив ctype [] в C / C ++ – также реализованный на Java. Эта концепция чрезвычайно полезна при обработке языков, особенно при использовании разных алфавитов или при анализе предложения.
ctype [] – это массив из 256 коротких целых чисел, а в каждом целочисленном – биты, представляющие разные типы символов. Например, ctype [; A ‘] – ctype [‘ Z ‘] имеют биты, установленные, чтобы показать, что они являются прописными буквами алфавита; ctype [‘0’] – ctype [‘9’] имеют биты, чтобы показать, что они числовые. Чтобы увидеть, является ли символ x буквенно-цифровым, вы можете написать что-то вроде «if (ctype [x] & (UC | LC | NUM))», которое несколько быстрее и намного элегантнее, чем писать «if (« A »= x < = 'Z' || .... '.
Когда вы начинаете думать поразрядно, вы найдете много мест для его использования. Например, у меня было два текстовых буфера. Я написал один к другому, заменив все вхождения FINDstring на REPLACEstring, когда я пошел. Затем для следующей пары find-replace я просто переключил индексы буфера, поэтому я всегда писал из буфера [in] в buffer [out]. ‘in’ начато как 0, ‘out’ как 1. После завершения копирования я просто написал ‘in ^ = 1; out ^ = 1; ‘. И после обработки всех заметок я просто написал буфер [out] на диск, не нуждаясь в том, чтобы знать, что такое «out» в то время.
Если вы считаете, что это низкий уровень, подумайте, что определенные умственные ошибки, такие как дежа-вю и его близнец-джамаиз-ву, вызваны ошибками мозгового бита!
Для работы с адресами IPv4 часто требуются битовые операции, чтобы обнаружить, находится ли адрес партнера в маршрутизируемой сети или должен быть перенаправлен на шлюз, или если одноранговый узел является частью сети, разрешенной или запрещенной правилами брандмауэра. Для обнаружения широковещательного адреса сети требуются битовые операции.
Для работы с адресами IPv6 требуются одни и те же основные операции на уровне бит, но поскольку они так длинны, я не уверен, как они реализованы. Я бы пообещал деньги, что они все еще реализованы с использованием операторов бит на кусках данных, соответствующих размерам архитектуры.