что должно быть x в __attribute__ ((выровнено (x)))

Я понимаю, что выравнивание переменных необходимо для эффективности. Чего я не понимаю, так это того, как определить правильный размер выравнивания. Насколько я понимаю, выровненное значение всегда должно быть установлено на размер слова процессора (т.е. 4 байта на 32-битной машине и 8 байтов на 64-битной машине) независимо от типа данных, чтобы чтение процессора выравнивалось с адресом переменная.

Например, зачем кому-то делать что-то вроде это. Я понимаю, что это просто проблема в какой-то книге по программированию. Имеет ли смысл использовать другие значения выравнивания, такие как в ссылке?


person nik    schedule 04.08.2011    source источник
comment
Выравнивания не в степени двойки очень редки и широко не поддерживаются.   -  person osgx    schedule 04.08.2011


Ответы (1)


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

type   size   align (bytes)
char     1       1
short    2       2
int      4       4
float    4       4
int64_t  8       8
double   8       8
long double (x87, 80 bit)  10  16
_float128  16    16
int128_t   16    16

Некоторые архитектуры, например. SPARC, запретить доступ к данным, если они не выровнены по 4 байтам, поэтому один символ будет иметь выравнивание по 4 байтам, и даже на архитектурах, допускающих такое поведение, доступ к данным, хранящимся с таким выравниванием, может быть быстрее; таким образом, локальные переменные в полях стека и структуры часто имеют заполнение для достижения этого, если у вас есть смесь типов разного размера, хотя это поведение можно изменить при желании.

Кэш работает быстрее с выравниванием не только по размеру слова (не 32 и 64 бита, а по размеру строки кэша, например, 16 байтов, 32 байта или 64 байта).

Некоторые более широкие инструкции, такие как SSE2 (ширина 128 бит) или double float (ширина 64 бита), быстрее (или иногда не работают) для выравнивания исходной ширины (если вам нужно загрузить 128-битные данные, вы должны выровнять их до 128 бит).

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

OpenCL (GPGPU) иногда требует серьезного согласования из-за очень широких шин DDR и ограничений доступа к памяти ядра графического процессора: http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/attributes.-variables.html

/* a has alignment of 128 */
 __attribute__((aligned(128))) struct A {int i;} a;
person osgx    schedule 04.08.2011
comment
вы также можете использовать __attribute__((aligned(4096))) для выравнивания элементов на границе страницы... - person Chris Dodd; 04.08.2011
comment
Крис Додд, нет. Не все компиляторы могут справиться с таким огромным выравниванием, поэтому лучше использовать memalign - person osgx; 04.08.2011
comment
Я не могу понять, почему тип данных должен быть выровнен с Native. - person nik; 04.08.2011
comment
Нативное выравнивание является режимом по умолчанию для некоторых компиляторов, и архитектура ЦП может дополнительно ограничивать это (требуется некоторое выравнивание для некоторых данных). Вот страница из MSVC msdn.microsoft.com/en-us/library/83ythb65 .aspx - person osgx; 04.08.2011