реклама на сайте
подробности

 
 
> Битовые поля vs битовые маски, Что лучше для эмбеддера?
sigmaN
сообщение Apr 17 2008, 21:05
Сообщение #1


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Доброго времени суток.

Битовые поля - кто за, кто против??

Да, знаю, что задаю в принципе извечный вопрос, однако ответа толкового в Интернете не нашел..
Кто-то говорит, что они помогают экономить память, кто-то - что эффективнее or'ить xor'ить и and'ить используя битовые маски и операции сдвига. Типа у bitfield overhead некий появляется, как плата за удобочитаемость....

Лично я склоняюсь к битовым маскам. Так мне привычнее и кажется, что для регистра лучше задефайнить что-то типа
#define BIT0 0x001
. . .
#define BIT15 0x8000
#define REGISTERx (*(volatile unsigned long *)(0x00D00))

а потом ставить биты REGISTERx|=BIT0+BIT3+BIT7;
или REGISTERx|=1<<7; //Ставим бит 7


Во всех примерах Техаса регистры закручены в битовые поля, они ссылаются друг на друга, адреса в линкер .cmd файле и т.д. и т.п.
Это же ужас! И никакой удобочитаемости это особо не добавляет. Часа два ушло у меня, чтобы толком разобраться что куда и откуда линкуется.
Неужели это всё может превзойти старые добрые методы?

Я всё-таки переделал на свой лад.
Потом задумался, а может зря... smile.gif Может особо ничего и не выиграл ))
Оперативка очень важна. Иду впритык, каждый байт на счету.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
DMax
сообщение Apr 17 2008, 22:26
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 161
Регистрация: 19-01-08
Из: Питер
Пользователь №: 34 234



Цитата(sigmaN @ Apr 18 2008, 01:05) *
Неужели это всё может превзойти старые добрые методы?


Может. Например, у того же техасовского TMS320C6x есть такая замечательная инструкция EXT. Она, по сути, заменяет собой две инструкции SHR и AND и служит для извлечения битового поля из регистра.

Если ты скажешь компилятору (путем объявления битовых полей), что один кусок слова - это поле A, а другой - это поле B и если компилятор не дурак (а в большинстве случаев он не дурак), то, скажем, чтение этих полей он будет осуществлять инструкцией EXT. А если ты не скажешь (будешь использовать маски), то вряд ли он догадается.

Существуют также и другие инструкции для манипулирования отдельными битами в словах. И они тоже будут использоваться компилятором.

Однако есть и минусы у такого подхода: стандарт C, если я правильно помню, ничего не говорит на тему того, какие биты слова должны ставиться в соответствие битовым полям. Так, имея два поля шириной 2 и 3 бита и 32-битную архитектуру, им может быть поставленно в соответствие 0-1 и 2-4 биты соотв., а может наоборот: 27-29 и 30-31. Если ты пишешь код, который отлаживаешь на писюке, а потом его же пускаешь на контролер, то тут могут возникнуть нюансы, которые зависят от твоих компиляторов. Но обычно, все же, имеет место здравый смысл, и поля заполняются по мере их объявления, заполняя младшие биты.

Цитата(sigmaN @ Apr 18 2008, 01:05) *
Оперативка очень важна. Иду впритык, каждый байт на счету.


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

Лично я, там где не критично, юзаю маски - привычнее и, ИМХО, нагляднее чуть-чуть. Где важна производительность, но при этом до асма спускаться лень, юзаю поля.
Go to the top of the page
 
+Quote Post
Major
сообщение Apr 18 2008, 04:02
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 375



Позволю заметить.
Стандарт не говорит каким будет представление bit-field в памяти, это на совести компилятора и архитектуры (big или little indian), НО:

#define FLAG_0 0x00000001
unsigned int x=0;
x = x | (FLAG_0);

и

union{
struct{
unsigned int FLAG0 : 1;
unsigned int : 31;
}bits;
unsigned int val;
}y
y.bits.FLAG0 = 1;

Будет полностью ролностью эквивалентно независимо от архитектур (расположения байт в памяти для Int, если слова меньше 32 бит).
Использование union+bitfields или флагов+переменные полностью эквивалентно.

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
страница 37:
Цитата
Values stored in unsigned bit-fields and objects of type unsigned char shall be
represented using a pure binary notation.40)

40) A positional representation for integers that uses the binary digits 0 and 1, in which the values
represented by successive bits are additive, begin with 1, and are multiplied by successive integral
powers of 2, except perhaps the bit with the highest position. (Adapted from the American National
Dictionary for Information Processing Systems.) A byte contains CHAR_BIT bits, and the values of
type unsigned char range from 0 to 2CHAR_BIT - 1.


Как уже отмечал, порядок байт в int зависит от компилера и платформы.

дополнение (начал перечитывать):
Цитата
10 An implementation may allocate any addressable storage unit large enough to hold a bitfield.
If enough space remains, a bit-field that immediately follows another bit-field in a
structure shall be packed into adjacent bits of the same unit. If insufficient space remains,
whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is
implementation-defined. The order of allocation of bit-fields within a unit (high-order to
low-order or low-order to high-order) is implementation-defined. The alignment of the
addressable storage unit is unspecified.


Если биты не влезли, то пакуются в в прилегающие биты (биту 0 прилегает бит 7) в такой же примитивный тип (char..int) как и предыдущие биты.
Если битов много, больше чем Int, то паковаться будет в два инта, а они могут располагаться в памяти в произвольных местах. Тут будет нужна прагма на упаковку вместе.
Или если операции идет с байтами, то паковка в байты идущие подряд, для многобайтовых полей не связаных в union.

Использовать union надо обязательно для примитивного типа:
Цитата
A union type describes an overlapping nonempty set of member objects, each of
which has an optionally specified name and possibly distinct type.


Ну стоит помнить что unsigned int может быть как 32 бита так и 16.
Ограничение определено как 16 и больше.
Цитата
The
minimum magnitudes shown shall be replaced by implementation-defined magnitudes
with the same sign.
#define UINT_MAX 65535
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- sigmaN   Битовые поля vs битовые маски   Apr 17 2008, 21:05
- - blackbit   Цитата(sigmaN @ Apr 18 2008, 01:05) Лично...   Apr 18 2008, 07:42
- - Сергей Борщ   Цитата(sigmaN @ Apr 18 2008, 00:05) Битов...   Apr 18 2008, 08:43
- - blackbit   Это да, если число изменяемых бит больше двух, то ...   Apr 18 2008, 08:55
- - sigmaN   Отлично! Значит правильно я сделал - сейчас ра...   Apr 18 2008, 09:34
|- - DMax   Цитата(sigmaN @ Apr 18 2008, 13:34) Гляну...   Apr 18 2008, 20:02
|- - sigmaN   Цитата(DMax @ Apr 18 2008, 23:02) Ты того...   Apr 19 2008, 08:15
|- - Сергей Борщ   Цитата(sigmaN @ Apr 19 2008, 11:15) Покор...   Apr 19 2008, 09:47
|- - zltigo   Цитата(sigmaN @ Apr 19 2008, 10:15) как-ж...   Apr 19 2008, 10:02
|- - Сергей Борщ   Цитата(zltigo @ Apr 19 2008, 13:02) Втора...   Apr 19 2008, 10:39
||- - DMax   Цитата(Сергей Борщ @ Apr 19 2008, 14:39) ...   Apr 19 2008, 12:01
|- - sigmaN   Цитата(zltigo @ Apr 19 2008, 13:02) А что...   Apr 19 2008, 11:27
|- - zltigo   Цитата(sigmaN @ Apr 19 2008, 13:27) Или ж...   Apr 19 2008, 11:37
- - sigmaN   Да суть-то я понимаю, почему они бьют ему ниже поя...   Apr 19 2008, 12:18


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th June 2025 - 16:39
Рейтинг@Mail.ru


Страница сгенерированна за 0.01384 секунд с 7
ELECTRONIX ©2004-2016