Маска (вычисление) - Mask (computing)
В информатике , А маска или битовая маска это данные, используемые для битовых операций , в частности , в битовом поле . Используя маску, несколько битов в байтах , полубайтах , словах и т. Д. Могут быть включены, выключены или инвертированы с включения на выключение (или наоборот) в одной побитовой операции. Дополнительное использование и значение маскирования включает в себя предсказание при обработке вектора , где битовая маска используется для выбора, какие операции с элементами в векторе должны выполняться (бит маски включен), а какие нет (бит маски очищен).
Общие функции битовой маски
Биты маскировки в 1
Чтобы включить определенные биты, можно использовать побитовыеOR
операции, следуя принципу, что Y OR 1 = 1
и Y OR 0 = Y
. Поэтому, чтобы убедиться, что бит включен, OR
его можно использовать с файлом 1
. Чтобы оставить немного без изменений, OR
используется с расширением 0
.
Пример: Маскировка на чем выше полубайте (биты 4, 5, 6, 7) нижняя часть байта (биты 0, 1, 2, 3) без изменений.
10010101 10100101 OR 11110000 11110000 = 11110101 11110101
Биты маскировки в 0
Чаще на практике, биты «замаскированы от » (или маскируются 0
) , чем «маскируются на » (или маскируются 1
). Когда бит AND
эд с 0, то результат всегда 0, то есть Y AND 0 = 0
. Чтобы оставить остальные биты такими, какими они были изначально, их можно AND
редактировать 1
какY AND 1 = Y
Пример: Маскировка от высших полубайт (биты 4, 5, 6, 7) нижней части байта (биты 0, 1, 2, 3) без изменений.
10010101 10100101 AND 00001111 00001111 = 00000101 00000101
Запрос статуса бита
Можно использовать битовые маски для простой проверки состояния отдельных битов независимо от других битов. Для этого отключение всех других битов с использованием побитового AND
выполняется, как описано выше, и значение сравнивается с 0
. Если он равен 0
, то бит был выключен, но если значение - любое другое значение, то бит был включен. Что делает это удобным, так это то, что нет необходимости выяснять, каково значение на самом деле, просто это не так 0
.
Пример: запрос состояния 4-го бита
10011101 10010101 AND 00001000 00001000 = 00001000 00000000
Переключение битовых значений
До сих пор в статье рассказывалось, как включать и выключать биты, но не то и другое сразу. Иногда на самом деле не имеет значения, какое значение имеет значение, но оно должно быть противоположным тому, что есть в настоящее время. Этого можно добиться с помощью операции XOR
(исключающее или) . XOR
возвращает 1
тогда и только тогда, когда нечетное количество битов 1
. Следовательно, если два соответствующих бита равны 1
, результатом будет a 0
, но если только один из них 1
, результат будет 1
. Следовательно, инверсия значений битов выполняется путем XOR
их добавления с помощью a 1
. Если исходный бит был 1
, он возвращается 1 XOR 1 = 0
. Если исходный бит был, 0
он возвращается 0 XOR 1 = 1
. Также обратите внимание, что XOR
маскирование является битобезопасным, что означает, что оно не повлияет на немаскированные биты, потому что Y XOR 0 = Y
, как и файл OR
.
Пример: переключение битовых значений
10011101 10010101 XOR 00001111 11111111 = 10010010 01101010
Чтобы записать произвольные единицы и нули в подмножество битов, сначала запишите 0 в это подмножество, а затем установите старшие биты:
register = (register & ~bitmask) | value;
Использование битовых масок
Аргументы к функциям
В языках программирования, таких как C , битовые поля - полезный способ передать набор именованных логических аргументов функции. Например, в графическом API OpenGL есть команда, glClear()
очищающая экран или другие буферы. Он может очищать до четырех буферов (буферы цвета, глубины, накопления и трафарета ), поэтому авторы API могли потребовать, чтобы он принимал четыре аргумента. Но тогда обращение к нему выглядело бы так
glClear(1,1,0,0); // This is not how glClear actually works and would make for unstable code.
что не очень наглядно. Вместо того, существует четыре определенных поля бит, GL_COLOR_BUFFER_BIT
, GL_DEPTH_BUFFER_BIT
, GL_ACCUM_BUFFER_BIT
, и GL_STENCIL_BUFFER_BIT
и glClear()
объявлен
void glClear(GLbitfield bits);
Тогда вызов функции выглядит так
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Внутренне функция, принимающая подобное битовое поле, может использовать двоичный файл and
для извлечения отдельных битов. Например, реализация glClear()
может выглядеть так:
void glClear(GLbitfield bits) {
if ((bits & GL_COLOR_BUFFER_BIT) != 0) {
// Clear color buffer.
}
if ((bits & GL_DEPTH_BUFFER_BIT) != 0) {
// Clear depth buffer.
}
if ((bits & GL_ACCUM_BUFFER_BIT) != 0) {
// Clear accumulation buffer.
}
if ((bits & GL_STENCIL_BUFFER_BIT) != 0) {
// Clear stencil buffer.
}
}
Преимущество этого подхода заключается в том, что уменьшаются накладные расходы на аргумент функции. Поскольку минимальный размер данных составляет один байт, разделение параметров на отдельные аргументы приведет к потере семи бит на аргумент и займет больше места в стеке. Вместо этого функции обычно принимают одно или несколько 32-битных целых чисел с до 32 битов опций в каждом. Несмотря на элегантность, в простейшей реализации это решение небезопасно по типам . A GLbitfield
просто определяется как an unsigned int
, поэтому компилятор допускает бессмысленный вызов glClear(42)
или даже glClear(GL_POINTS)
. В C ++ альтернативой было бы создание класса для инкапсуляции набора аргументов, которые glClear мог бы принять и которые можно было бы чисто инкапсулировать в библиотеке.
Обратные маски
Маски используются с IP-адресами в IP ACL (списках контроля доступа), чтобы указать, что должно быть разрешено, а что запрещено. Чтобы настроить IP-адреса на интерфейсах, маски начинаются с 255 и имеют большие значения слева: например, IP-адрес 203.0.113.129 с маской 255.255.255.224 . Маски для списков управления доступом IP обратные: например, маска 0.0.0.255 . Иногда это называется обратной маской или подстановочной маской . Когда значение маски разбивается на двоичные (0 и 1), результаты определяют, какие биты адреса следует учитывать при обработке трафика. 0 -битных указывает на то, что адрес бит должен рассматриваться (точное совпадение); 1 -битовых в маске «не все равно». Эта таблица дополнительно объясняет концепцию.
Пример маски:
сетевой адрес (трафик, который нужно обработать): 192.0.2.0
маска: 0.0.0.255
сетевой адрес (двоичный): 11000000.00000000.00000010.00000000
маска (двоичная): 00000000.00000000.00000000.11111111
Основываясь на двоичной маске, можно увидеть, что первые три набора ( октета ) должны точно соответствовать заданному двоичному сетевому адресу (11000000.00000000.00000010). Последний набор чисел состоит из «безразлично» (.11111111). Следовательно, весь трафик, который начинается с « 192.0.2. », Соответствует , поскольку последний октет - «безразлично». Следовательно, с этой маской обрабатываются сетевые адреса с 192.0.2.0.1 по 192.0.2.0.255 ( 192.0.2.0.x ).
Вычтите нормальную маску из 255.255.255.255 , чтобы определить инверсную маску ACL. В этом примере обратная маска определяется для сетевого адреса 198.51.100.0 с нормальной маской 255.255.255.0 .
255.255.255.255 - 255.255.255.0 (нормальная маска) = 0.0.0.255 (обратная маска)
Эквиваленты ACL
Исходный / исходный-подстановочный знак 0.0.0.0 / 255.255.255.255 означает «любой».
Источник / подстановочный знак 198.51.100.2 / 0.0.0.0 совпадает с "хостом 198.51.100.2 "
Маски изображения
В компьютерной графике , когда данное изображение предназначено для размещения на фоне, прозрачные области могут быть указаны с помощью двоичной маски. Таким образом, для каждого предполагаемого изображения фактически есть два растровых изображения : фактическое изображение, в котором неиспользуемым областям присваивается значение пикселя со всеми битами, установленными в 0, и дополнительная маска , в которой соответствующим областям изображения присваивается значение пикселя. для всех битов установлено значение 0, а для окружающих областей значение всех битов установлено в 1 с. В примере справа черные пиксели имеют нулевые биты, а белые пиксели - все единицы.
Во время выполнения , чтобы поместить изображение на экран поверх фона, программа сначала маскирует биты пикселя экрана с помощью маски изображения в желаемых координатах с помощью побитовой операции AND . Это сохраняет фоновые пиксели прозрачных областей и обнуляет биты пикселей, которые будут скрыты перекрывающимся изображением.
Затем программа визуализирует биты пикселя изображения, комбинируя их с битами фонового пикселя, используя операцию побитового ИЛИ . Таким образом пиксели изображения размещаются надлежащим образом с сохранением окружающих пикселей фона. В результате получается идеальное соединение изображения с фоном.
Этот метод используется для рисования курсоров указывающих устройств в типичных двухмерных видеоиграх для символов, маркеров и т. Д. ( Спрайтов ), для значков графического интерфейса пользователя , а также для титров видео и других приложений для смешивания изображений.
Хотя прозрачные цвета и альфа-каналы связаны (поскольку используются для одних и тех же целей), это методы, которые не включают смешение пикселей изображения путем двоичного маскирования.
Хеш-таблицы
Чтобы создать хеш-функцию для хеш-таблицы , часто используется функция с большим доменом. Чтобы создать индекс из вывода функции, можно взять по модулю, чтобы уменьшить размер домена, чтобы он соответствовал размеру массива; однако на многих процессорах часто бывает быстрее ограничить размер хеш-таблицы степенями двух размеров и вместо этого использовать битовую маску.
Пример как по модулю, так и маскировки в C:
#include <stdint.h>
#include <string.h>
int main(void) {
const uint32_t NUM_BUCKETS = 0xFFFFFFFF; // 2^32 - 1
const uint32_t MAX_RECORDS = 1<<10; // 2^10
const uint32_t HASH_BITMASK = 0x3FF; // (2^10)-1
char **token_array = NULL;
// Handle memory allocation for token_array…
char token[] = "some hashable value";
uint32_t hashed_token = hash_function(token, strlen(token), NUM_BUCKETS);
// Using modulo
size_t index = hashed_token % MAX_RECORDS;
// OR
// Using bitmask
size_t index = hashed_token & HASH_BITMASK;
*(token_array+index) = token;
// Free the memory from token_array …
return 0;
}