Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Выравнивание переменных в памяти  (Прочитано 11422 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Vorlon
Гость
« : 30-11-2003 17:48 » 

VC6.0, описываю такую структуру

struct StructName
{
BYTE Data1[0x0F]; // число элементов нечетное
WORD Var1,Var2;
...
};

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

Желательно, выравнивание слов по четным адресам отменить именно для этой структуры, а не для всей программы.
Записан
Alf
Гость
« Ответ #1 : 30-11-2003 18:21 » 

По идее, использование конструкции
Код:
#pragma pack) [ n( :

должно помочь с этой проблемой.
n может принимать значение 1, 2, 4, 8 или 16 (по умолчанию - 8 ) и задает выравнивание каждого члена структуры по границе, кратной n байт.
Конструкция действует на первое следующее объявление структуры, так что во всей остальной программы выравнивание должно остаться по умолчанию.
Естественно, как и все конструкции с использованием pragma, данная специфична для MS VC++ 6.0 и не является переносимой.
Записан
Vorlon
Гость
« Ответ #2 : 30-11-2003 19:07 » 

Alf, благодарю за подсказку, помогло!
Записан
grozny
Гость
« Ответ #3 : 01-12-2003 06:24 » 

ещё есть declspec(align(#bytes)). Появился в VC 7.0. Аргумент - кол-во байт, обязательно степень двойки от 1 до 8192 (pragma pack кончается на 8).

Удобен ещё и тем, что можно узнать выравнивание переменной или типа оператором __alignof(имя)

Цитата из МСДН 2003 (с полезным примером выравнивания по размеру кэши):
...
The following examples show how __declspec(align(#)) affects the size and alignment of data structures. The examples assume the following definitions:

#define CACHE_LINE  32
#define CACHE_ALIGN __declspec(align(CACHE_LINE))
In the following example, the S1 structure is defined with __declspec(align(32)). All uses of S1, whether for a variable definition or other type declarations, ensure that this structure data is 32-byte aligned. sizeof(struct S1) returns 32, and S1 has 16 padding bytes following the 16 bytes required to hold the four integers. Each int member requires 4-byte alignment, but the alignment of the structure itself is declared to be 32, so the overall alignment is 32.

struct CACHE_ALIGN S1  // cache align all instances of S1{
   int a, b, c, d;
};
struct S1 s1;   // s1 is 32-byte cache aligned
In the following example, sizeof(struct S2) will return 16, which is exactly the sum of the member sizes, because that happens to be a multiple of the largest alignment requirement (a multiple of 8).

__declspec(align(8)) struct S2
{
   int a, b, c, d;
};
In the following example, sizeof(struct S3) returns 64.

struct S3
{
   struct S1 s1;   // S3 inherits cache alignment requirement
                  // from S1 declaration
   int a;         // a is now cache aligned because of s1
                  // 28 bytes of trailing padding
};
In the following example, note that a has only the alignment of natural type, in this case, 4 bytes. However, S1 must be 32-byte aligned. Twenty-eight bytes of padding follow a, so that s1 starts at offset 32. S4 then inherits the alignment requirement of S1, because it is the largest alignment requirement in the structure. sizeof(struct S4) returns 64.

struct S4
{
   int a;
   // 28 bytes padding
    struct S1 s1;      // S4 inherits cache alignment requirement of S1
};
The following three variable declarations also use __declspec(align(#)). In each case, the variable must be 32-byte aligned. In the case of the array, the base address of the array, not each array member, is 32-byte aligned. The sizeof value for each array member is not affected by the use of __declspec(align(#)).

CACHE_ALIGN int i;
CACHE_ALIGN int array[128];
CACHE_ALIGN struct s2 s;
To align each individual member of an array, code such as the following should be used:

typedef CACHE_ALIGN struct { int a; } S5;
S5 array[10];
In the following example, note that aligning the structure itself and aligning the first element are identical:

CACHE_ALIGN struct S6
{
   int a;
   int b;
};

struct S7
{
   CACHE_ALIGN int a;
               int b;
};
S6 and S7 have identical alignment, allocation, and size characteristics.

Defining New Types with __declspec(align(#))
You can define a type with an alignment characteristic.

For example, you can define a struct with an alignment value as follows:

struct aType {int a; int b;};
typedef __declspec(align(32)) struct aType bType;
Now, aType and bType are the same size (8 bytes) but variables of type bType will be 32-byte aligned.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines