Битовые поля в C и C++: где они используются?


person Ilya Tereschuk    schedule 03.01.2014    source источник
comment
Попробуйте написать столбчатую базу данных переменного размера.   -  person Elliott Frisch    schedule 03.01.2014
comment
Это немного широко. Но низкоуровневая сериализация в зависимости от платформы может выиграть от битовых полей, как и большие структуры данных в памяти, работа с кэшем, привязанная к памяти, и т. д.   -  person Yakk - Adam Nevraumont    schedule 03.01.2014
comment
@Yakk На самом деле их нельзя использовать для сериализации, потому что многое не указано в отношении того, как они расположены.   -  person James Kanze    schedule 03.01.2014
comment
@JamesKanze Важна фраза, зависящая от платформы: неуказанный стандартом макет не означает неуказанный вашим компилятором, и многие компиляторы размещают их красиво упакованным образом и стабильны между итерациями компилятора.   -  person Yakk - Adam Nevraumont    schedule 03.01.2014
comment
Их можно использовать во встроенных процессорах для битовой упаковки коммуникационных протоколов, упаковки данных, отображения флагов регистров. Это зависит от знания того, как упаковывается компилятор, поэтому он зависит от данной комбинации компилятор/процессор. Но это вполне приемлемо, когда вы пишете для очень специфического встраиваемого оборудования.   -  person AShelly    schedule 03.01.2014
comment
@Yakk Некоторые компиляторы (я полагаю) документируют это, но это привязывает вас к конкретному компилятору. И большинство компиляторов этого не делают. (Я не нашел такой документации ни в одном из компиляторов, которые я использовал.)   -  person James Kanze    schedule 03.01.2014
comment
Я отредактировал вопрос, пожалуйста, откройте снова, не дайте ему умереть   -  person Ilya Tereschuk    schedule 03.01.2014
comment
@ElliotTereschuk - это редактирование вряд ли заслуживает повторного открытия. Но подумайте об этом - у вас есть МНОГО объектов со свойствами, которые могут быть выражены в нескольких битах, это идеальный сценарий для использования битовых полей. Например, 8 логических свойств будут занимать 8 байт, если они сохранены в bool, но с битовыми полями они будут занимать только 1 байт.   -  person dtech    schedule 03.01.2014
comment
@ElliotTereschuk Это все еще вопрос опроса. SO стремится ответить на конкретные проблемы, для которых есть решение. Вопрос, как написано, будет иметь много ответов. Это интересно, но текущие стандарты SO говорят, что здесь не стоит задавать вопрос.   -  person Yakk - Adam Nevraumont    schedule 04.01.2014


Ответы (4)


Есть несколько вариантов использования битовых полей даже на современных машинах.

Во-первых, когда вы обрабатываете логику уровня регистра. Это обычное дело, когда вы устанавливаете режимы и то, как работают определенные части оборудования. Это еще более распространено на встроенных устройствах. Например, на устройствах Arduino логика «PinMode» в основном устанавливает отдельные биты в высокий или низкий уровень, чтобы указать, находится ли цифровой вывод ввода-вывода в режиме «ввод» или «выход».

http://arduino.cc/en/Reference/pinMode

Во-вторых, при написании оптимизированного встроенного ассемблерного кода в программе на C/C++. Бывают случаи, когда вы хотите воспользоваться аппаратно-оптимизированными инструкциями, чтобы максимально ускорить выполнение вашей программы:

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

Последний распространенный пример — написание пакетных драйверов или реализация определенных протоколов. Недавно я только что опубликовал вопрос по этому поводу, где оказалось, что я использовал 32-битную переменную вместо 8-битной переменной, состоящей из битовых полей, что приводило к поломке моего кода:

Базовый клиент NTP в Windows в Visual C++

Итак, вкратце: при разговоре напрямую с оборудованием или в сетевом коде.

person Cloud    schedule 03.01.2014

При работе со встроенными системами и микроконтроллерами отдельные биты в регистре могут быть связаны с настройкой процессора или вводом/выводом. Использование битовых полей позволяет работать с этими отдельными битами по имени вместо выполнения побитовых операций над всем регистром.

В основном это эстетическая функция, но она может повысить читаемость кода в некоторых приложениях.

person 1337 on Tuesdays    schedule 03.01.2014
comment
За исключением того, что они не работают для этого, если ваш компилятор не указывает иное. (Что, конечно, привязывает вас к одному конкретному компилятору. Но большинство встраиваемых систем в любом случае будут более или менее привязаны к конкретному компилятору.) - person James Kanze; 03.01.2014

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

person James Kanze    schedule 03.01.2014
comment
Речь идет не только об экономии памяти (на самом деле, это, вероятно, одно из наименее распространенных применений). Отображение битовых полей регистров для SoC и микроконтроллеров более вероятно. Например, в этом заголовке PIC16 широко используются битовые поля, как и в заголовках, специфичных для большинства микроконтроллеров и SoC. - person Clifford; 04.01.2014
comment
Встроенная сборка по-прежнему распространена в современных процессорах. MATLAB, например, широко использует оптимизации для конкретных платформ. Некоторый код включает в себя явную установку определенных регистров. - person Cloud; 04.01.2014

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

Экономьте память, объединяя свойства, которым требуется несколько битов для выражения диапазона возможных значений. Зачем помещать 8 логических свойств как 8 bool членов, когда один байт дает возможность хранить 8 логических значений в каждом бите - вместо 8 байтов вы используете только 1, 7 сэкономленных байтов довольно значительно. Естественно, вы обычно используете 32-, 64-битные или более широкие битовые поля. У меня есть аналогичный сценарий с большим количеством объектов с множеством свойств, которые могут быть выражены в одном или нескольких битах, и для случаев с большим количеством объектов (миллионы) экономия памяти действительно значительна.

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

person dtech    schedule 03.01.2014