Битовые операции абсолютно необходимы при программировании аппаратных регистров во встроенных системах. Например, каждый процессор, который я когда-либо использовал, имеет один или несколько регистров (обычно это определенный адрес памяти), которые управляют включением или отключением прерывания. Чтобы позволить прерыванию запускаться, обычный процесс должен установить бит разрешения для этого одного типа прерывания, и, самое главное, не изменять ни один из других битов в регистре.
Когда прерывание срабатывает, оно, как правило, устанавливает бит в регистре состояния, чтобы одна процедура обслуживания могла определить точную причину прерывания. Тестирование отдельных битов позволяет быстро декодировать источник прерывания.
Во многих встроенных системах общий объем доступной оперативной памяти может составлять 64, 128 или 256 байт (то есть байтов, а не килобайт или мегабайт). В этой среде обычно используется один байт для хранения нескольких элементов данных, логических флагов и т. Д., А затем используются битовые операции. установить и прочитать это.
В течение ряда лет я работал со спутниковой системой связи, в которой полезная нагрузка сообщения составляет 10,5 байта. Чтобы наилучшим образом использовать этот пакет данных, информация должна быть упакована в блок данных, не оставляя неиспользованных битов между полями. Это означает, что необходимо широко использовать побитовые и сдвиговые операторы для получения информационных значений и их упаковки в передаваемую полезную нагрузку.
В основном, вы используете их из-за размера и скорости. Побитовые операции невероятно просты и, следовательно, обычно быстрее, чем арифметические операции. Например, чтобы получить зеленую часть значения rgb, используется арифметический подход
(rgb / 256) % 256
. С побитовыми операциями вы бы сделали что-то как(rgb >> 8) & 0xFF
. Последнее значительно быстрее, и как только вы к нему привыкнете, это также проще. Как правило, побитовые операции играют важную роль, когда вам необходимо компактно и быстро кодировать / декодировать данные.источник
BYTE g1 = (rgb / 256) % 256;
00E51013...C1 E9 08...shr ecx,8
00E51016...88 0C 24...mov byte ptr [esp],cl
Этот вид операций часто используется при записи для встроенных систем, где память или мощность процессора ограничены.
Например, чтобы сэкономить место, вы можете хранить несколько переменных в одной 8-битной переменной int, используя каждый бит для представления логического значения. Затем вам нужен быстрый способ установить определенный бит или получить значение бита.
Обычно при программировании на языках более высокого уровня, таких как C #, на настольном ПК с гигабайтами памяти, вам не важно, что каждый из них
bool
занимает целый байт . Но если вы программируете микроконтроллер на C с 2 КБ памяти, каждый бит считается, поэтому возможность упаковки 8 bools в один байт может оказаться критической.источник
[Flags]
атрибут, который позволяет использоватьEnum
в качестве битового поля. Например,Font
имеетStyle
свойство, представляющее собой битовое поле, содержащее жирный, курсив, подчеркивание и зачеркивание.Побитовые операции также часто используются в видео и аудио кодеках по той же причине, что и во встроенной электронике; возможность упаковать пять флагов и одиннадцать-битный таймер в половину целого числа очень полезна, когда вы хотите создать суперэффективный видеокодек.
Фактически, MPEG 4 даже использует экспоненциальное кодирование Голомба для полей переменной битовой длины. Значение последнего пакета шириной 17 или 19 битов может составлять всего три или пять битов в этом пакете - и вы разберетесь с побитовыми операциями.
источник
Уловки, которые объединяют побитовые логические операции, побитовые операции сдвига и арифметические операции, могут быть поняты людьми, которые изучали конструкцию двоичного сумматора с использованием логических вентилей (и, или, нет). За пределами этого круга это очень трудно понять без подробного комментария.
Это полезно при программировании SIMD- блоков, особенно если архитектура процессора преднамеренно не учитывает некоторые SIMD-инструкции, потому что они могут эмулироваться несколькими другими.
Например, архитектура может не определять какие-либо инструкции для получения отрицательных значений группы из 16 байтов, но это может быть эмулировано путем побитового отрицания и последующего добавления 1. Аналогично вычитание также может быть опущено, потому что его можно эмулировать, взяв отрицание второго операнда. Наличие «альтернативного маршрута» является причиной пропуска определенных инструкций.
Аналогично, SIMD может поддерживать только параллельное 8-битное сложение, без реализации сложения для более широких элементов, таких как 16-битный, 32-битный или 64-битный. Чтобы эмулировать их, необходимо извлечь знаковый бит из 8-разрядного результата вычисления, а затем выполнить операцию переноса для следующего элемента.
источник
Упаковка данных, более быстрые операции (умножение, деление и модуль) значительно быстрее, если выровнять их по степеням 2), переворачивание битов и т. Д. Изучите их и начните их использовать, и вы постепенно начнете видеть большинство преимуществ самостоятельно.
источник