187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335

sizeof на битовую структуру

20.10.2012, 07:38. Показов 2896. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Данный код структуры :
C++
1
2
3
4
5
6
7
8
#pragma pack(push, 1)
 
struct FIELD
{ 
    unsigned x : BITS_COUNT; 
};
 
#pragma pack(pop)
воспринимается
C++
1
sizeof(FIELD);
как 4 байта, где
C++
1
#define BITS_COUNT 24
Вопрос : почему?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.10.2012, 07:38
Ответы с готовыми решениями:

Sizeof(.) или constexpr size_t tmp = sizeof(.)
sizeof(...) или constexpr size_t tmp = sizeof(...) Как лучше с точки зрения производительности? правильности?

Fwrite (buffer , sizeof(char), sizeof(buffer), pFile)
как записать часть массива чаров? допустим у нас arr; мне надо записать с позиции массива 500 до 600, 100 байтов как записать эту...

Можно ли на 32 битовую систему установить 64 битовую sql server?
можно ли на 32 битовую систему установить 64 битовую sql server?

27
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
21.10.2012, 10:37
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Герц Посмотреть сообщение
Это лучше чем каждый бит или несколько вытаскивать по маске и выравнивать оператором сдвига.
Вот как раз нет. Лучше (с точки зрения эффективности кода) делать это именно ручками. В идеале, оформив в виде класса и inline методами. Битовые поля крайне неэффективны (по крайней мере там было в течении многих веков, возможно это уже не является проблемой для компилятора).
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21283 / 8308 / 637
Регистрация: 30.03.2009
Сообщений: 22,670
Записей в блоге: 30
21.10.2012, 10:49
Цитата Сообщение от Deviaphan Посмотреть сообщение
Вот как раз нет. Лучше (с точки зрения эффективности кода) делать это именно ручками. В идеале, оформив в виде класса и inline методами. Битовые поля крайне неэффективны (по крайней мере там было в течении многих веков, возможно это уже не является проблемой для компилятора).
Любой современный компилятор с битовыми полями справится так же, как и с битовыми операциями. Старые компиляторы на intel'е навряд ли дадут выигрыш при работе с битовыми операциями, т.к. получается много промежуточных значений, а регистров мало и всё равно что-то начнёт попадать в стек
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
21.10.2012, 12:09
Почти ни разу не пользовался битовыми полями, поэтому захотелось сравнить в "полевых" условиях.
Пример специально "запутан", чтобы компилятор не сумел оптимизировать то, чего сравнить хотелось.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "stdafx.h"
#include <iostream>
using namespace std;
 
typedef unsigned int Field;
 
struct Color16bitS
{ 
    Field r : 5;
    Field g : 5;
};
 
class Color16bit
{
public:
    void SetR(Field r)
    {
        rgbk &= 0xE0;
        rgbk |= r;
    }
 
    Field GetR() const
    {   return rgbk & 0x1F; }
 
    void SetG(Field g)
    {
        rgbk &= 0xF5EF;
        rgbk |= (g<<5);
    }
 
    Field GetG() const
    {   return (rgbk >> 5) & 0x1F;  }
 
 
    Field rgbk;
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    Field r, g;
    cin >> r >> g;
 
    {
        Color16bitS f;
                
        f.r = r;
        f.g = g;
 
        Field sum = 0;
        if( f.r > 3 )
            sum = f.r + f.g;
        else
        {
            f.r = 0;
        }
 
        cout << sum << " " <<  sizeof(f) << endl;
    }
    
    {
        Color16bit f;
 
        f.SetR(r);
        f.SetG(g);
 
        Field sum = 0;
        if( f.GetR() > 3 )
            sum = f.GetR() + f.GetG();
        else
            f.SetR(0);
 
        cout << sum << " " << sizeof(f) << endl;
    }
 
    cin.get();
    return 0;
}
Оно же (компилятор msvc2010 с оптимизацией по скорости)
Оставил только интересный фрагменты
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    mov eax, DWORD PTR _g$[esp+8]
    mov edx, DWORD PTR _f$22438[esp+8]
    mov ecx, DWORD PTR _r$[esp+8]
    and eax, 31                 ; 0000001fH
    shl eax, 5
    and edx, -1024              ; fffffc00H
    and ecx, 31                 ; 0000001fH
    or  eax, edx
    or  eax, ecx
 
; 51   : 
; 52   :        Field sum = 0;
; 53   :        if( f.r > 3 )
 
    mov ecx, eax
    and ecx, 31                 ; 0000001fH
    xor edx, edx
    cmp ecx, 3
    jbe SHORT $LN4@wmain
 
; 54   :            sum = f.r + f.g;
 
    shr eax, 5
    and eax, 31                 ; 0000001fH
    lea edx, DWORD PTR [ecx+eax]
$LN4@wmain:
 
 
 
; 63   :    {
; 64   :        Color16bit f;
; 65   : 
; 66   :        f.SetR(r);
; 67   :        f.SetG(g);
 
    mov eax, DWORD PTR _f$22582[esp+8]
    mov ecx, DWORD PTR _g$[esp+8]
    and eax, 224                ; 000000e0H
    or  eax, DWORD PTR _r$[esp+8]
    shl ecx, 5
    and eax, 62959              ; 0000f5efH
    or  eax, ecx
 
; 68   : 
; 69   :        Field sum = 0;
; 70   :        if( f.GetR() > 3 )
 
    mov ecx, eax
    and ecx, 31                 ; 0000001fH
    xor edx, edx
    cmp ecx, 3
    jbe SHORT $LN2@wmain
 
; 71   :            sum = f.GetR() + f.GetG();
 
    shr eax, 5
    and eax, 31                 ; 0000001fH
    lea edx, DWORD PTR [ecx+eax]
$LN2@wmain:
Получается, что написанный вручную код всего на две операции шустрее битовых полей. Реализовывать структуру полностью мне было лень (там ещё поле для blue и один бит на colorKey должны быть). Похоже, что чем больше полей, тем больше будет выигрыш при написании вручную, но придётся писать вручную. Много. И муторно. Проще забить и использовать битовые поля.
Наименьшее число операций ри использовании типа unisgned int. При использовании int или (unsigned)short число операций возрастает для обоих методов.
В общем, забиваем на всё и используем битовые поля, но только с типом unsigned int.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21283 / 8308 / 637
Регистрация: 30.03.2009
Сообщений: 22,670
Записей в блоге: 30
21.10.2012, 13:50
Я интеловский ассемблер как-то плохо понимаю, а потому вот так глядя на код немного не фтыкаю (надо моск напрягать). С виду по исходнику всё написано правильно и код не должен отличаться. Надо попробовать на свежую голову понять, почему при записи битовых полей код получился длиннее (там немного по математической части кумекать надо, может просто компилятор недостаточно качественно соптимизировал)
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
21.10.2012, 14:18
Присваивание значений какое-то мутное в битовых полях.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21283 / 8308 / 637
Регистрация: 30.03.2009
Сообщений: 22,670
Записей в блоге: 30
22.10.2012, 00:11
Ничего мутного нет
Расскажите про new и delete в C++
1
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
22.10.2012, 06:03
Цитата Сообщение от Evg Посмотреть сообщение
Ничего мутного нет
Так вручную же я те же самые операции делаю: считывание "подложки", обнуление соответствующих битов, сдвиг и добавление.

А в чём разница до меня дошло! Вручную я не проверял, что вводимое значение на корректность (размер в битах), а битовые поля проверку выполняют (and ecx, 31), на всякий случай обнуляя лишние биты. Если добавить код проверки в класс Color16bit, то вообще никакой разницы не будет между ручной реализацией и битовым полем. Так что забываю про то, что битовые поля не эффективные.

Добавлено через 1 минуту
Цитата Сообщение от Deviaphan Посмотреть сообщение
до меня дошло!
А щяс и комментарий в твоей ссылке прочитал и дважды дошло.)
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21283 / 8308 / 637
Регистрация: 30.03.2009
Сообщений: 22,670
Записей в блоге: 30
22.10.2012, 08:50
Цитата Сообщение от Deviaphan Посмотреть сообщение
Вручную я не проверял, что вводимое значение на корректность
Да, проморгал я этот момент....

Цитата Сообщение от Deviaphan Посмотреть сообщение
Так что забываю про то, что битовые поля не эффективные
Единственная их неэффективность могла бы заключаться в том, что структуру компилятор чаще загоняет в стек, чем скалярное значение. В современных компиляторах это пофигу, а вот в старых в этом месте действительно могла просочиться неэффективность.

А что касается чтения/записи полей, то на некоторых процессорах (где-то видел, но не помню, где именно) есть специальные операции для этого дела. Теоретически компилятор может и битовую арифметику к этим операциям свести, но практически надо проверять
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.10.2012, 08:50

Как установить 32 битовую версию на 64 битовую ОС?
Проблема с установкой связи из МАТЛАБ к SQL server 2008. Win 64, МАаТЛАБ 64 и SQL server 64 бита. при попытке установить связь с БД...

Является ли оператор sizeof синтаксическим сахаром над System.Runtime.InteropServices.Marshal.SizeOf?
Является ли оператор sizeof синтаксическим сахаром над System.Runtime.InteropServices.Marshal.SizeOf?

Что обозначает строка вида sizeof(data)/sizeof(data[0])?
#include &quot;stdafx.h&quot; #include &lt;stdio.h&gt; void bubble_sort(float *data, int size) { int i,j; for (i = 0; i &lt; size; ++i) { ...

Marshal.SizeOf и sizeof
чем отличаются Marshal.SizeOf и sizeof? я просто почему то привык пользоваться Marshal.SizeOf, так вот иногда это приводит к интересным...

Задача на битовую магию
Развлекался с модулем АЦП в одной STM-ке и наткнулся на интересную задачу. Сама задача к контроллерам не привязана, поэтому и тему создаю в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Опции темы

Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru