Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 8, средняя оценка - 4.75
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
20.10.2012, 07:38     sizeof на битовую структуру #1
Данный код структуры :
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
Вопрос : почему?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
21.10.2012, 10:37     sizeof на битовую структуру #21
Цитата Сообщение от Герц Посмотреть сообщение
Это лучше чем каждый бит или несколько вытаскивать по маске и выравнивать оператором сдвига.
Вот как раз нет. Лучше (с точки зрения эффективности кода) делать это именно ручками. В идеале, оформив в виде класса и inline методами. Битовые поля крайне неэффективны (по крайней мере там было в течении многих веков, возможно это уже не является проблемой для компилятора).
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16821 / 5242 / 318
Регистрация: 30.03.2009
Сообщений: 14,118
Записей в блоге: 26
21.10.2012, 10:49     sizeof на битовую структуру #22
Цитата Сообщение от Deviaphan Посмотреть сообщение
Вот как раз нет. Лучше (с точки зрения эффективности кода) делать это именно ручками. В идеале, оформив в виде класса и inline методами. Битовые поля крайне неэффективны (по крайней мере там было в течении многих веков, возможно это уже не является проблемой для компилятора).
Любой современный компилятор с битовыми полями справится так же, как и с битовыми операциями. Старые компиляторы на intel'е навряд ли дадут выигрыш при работе с битовыми операциями, т.к. получается много промежуточных значений, а регистров мало и всё равно что-то начнёт попадать в стек
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
21.10.2012, 12:09     sizeof на битовую структуру #23
Почти ни разу не пользовался битовыми полями, поэтому захотелось сравнить в "полевых" условиях.
Пример специально "запутан", чтобы компилятор не сумел оптимизировать то, чего сравнить хотелось.
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.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16821 / 5242 / 318
Регистрация: 30.03.2009
Сообщений: 14,118
Записей в блоге: 26
21.10.2012, 13:50     sizeof на битовую структуру #24
Я интеловский ассемблер как-то плохо понимаю, а потому вот так глядя на код немного не фтыкаю (надо моск напрягать). С виду по исходнику всё написано правильно и код не должен отличаться. Надо попробовать на свежую голову понять, почему при записи битовых полей код получился длиннее (там немного по математической части кумекать надо, может просто компилятор недостаточно качественно соптимизировал)
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
21.10.2012, 14:18     sizeof на битовую структуру #25
Присваивание значений какое-то мутное в битовых полях.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16821 / 5242 / 318
Регистрация: 30.03.2009
Сообщений: 14,118
Записей в блоге: 26
22.10.2012, 00:11     sizeof на битовую структуру #26
Ничего мутного нет
Расскажите про new и delete в C++
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
22.10.2012, 06:03     sizeof на битовую структуру #27
Цитата Сообщение от Evg Посмотреть сообщение
Ничего мутного нет
Так вручную же я те же самые операции делаю: считывание "подложки", обнуление соответствующих битов, сдвиг и добавление.

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

Добавлено через 1 минуту
Цитата Сообщение от Deviaphan Посмотреть сообщение
до меня дошло!
А щяс и комментарий в твоей ссылке прочитал и дважды дошло.)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.10.2012, 08:50     sizeof на битовую структуру
Еще ссылки по теме:

C++ Как получить битовую маску вида 100.000
sizeof() C++
C++ Sizeof глючит ?

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16821 / 5242 / 318
Регистрация: 30.03.2009
Сообщений: 14,118
Записей в блоге: 26
22.10.2012, 08:50     sizeof на битовую структуру #28
Цитата Сообщение от Deviaphan Посмотреть сообщение
Вручную я не проверял, что вводимое значение на корректность
Да, проморгал я этот момент....

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

А что касается чтения/записи полей, то на некоторых процессорах (где-то видел, но не помню, где именно) есть специальные операции для этого дела. Теоретически компилятор может и битовую арифметику к этим операциям свести, но практически надо проверять
Yandex
Объявления
22.10.2012, 08:50     sizeof на битовую структуру
Ответ Создать тему
Опции темы

Текущее время: 02:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru