Маска (вычисление) - 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;

Использование битовых масок

Уловка для вечеринки, позволяющая угадать число, на каких карточках оно напечатано, использует биты двоичного представления числа. В файле SVG щелкните карточку, чтобы переключить ее

Аргументы к функциям

В языках программирования, таких как 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 . Это сохраняет фоновые пиксели прозрачных областей и обнуляет биты пикселей, которые будут скрыты перекрывающимся изображением.

Затем программа визуализирует биты пикселя изображения, комбинируя их с битами фонового пикселя, используя операцию побитового ИЛИ . Таким образом пиксели изображения размещаются надлежащим образом с сохранением окружающих пикселей фона. В результате получается идеальное соединение изображения с фоном.

Рендеринг спрайтов с помощью двоичного изображения mask.png

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

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

Хеш-таблицы

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

Пример как по модулю, так и маскировки в 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;
}

Смотрите также

использованная литература