Что такое выравнивание структур?
От: DIMEDROLL Украина  
Дата: 17.10.09 09:33
Оценка:
Увидел термин в какой то доке, поискал в инете. Из того что понял:
Это добавление "пустых" данных к обьектам-членам структуры.
Для чего?
Что бы ускорить доступ процессора к этим данным.
Выравнивание(тоесть дополнение) выполняет компилятор, в настройках которого и можно задать количество байт для каждого члена структуры.
Поправьте если где ошибся.
Возникли вопросы.
Где и кем это применяется и для чего? Что это дает еще, кроме того что я указал. Практические примеры.
Киньте ссылкой на толковую доку и примеры или на название книги.
Re: Что такое выравнивание структур?
От: LaptevVV Россия  
Дата: 17.10.09 10:35
Оценка:
Здравствуйте, DIMEDROLL, Вы писали:

DIM>Увидел термин в какой то доке, поискал в инете. Из того что понял:

DIM>Это добавление "пустых" данных к обьектам-членам структуры.
DIM>Для чего?
DIM>Что бы ускорить доступ процессора к этим данным.
DIM>Выравнивание(тоесть дополнение) выполняет компилятор, в настройках которого и можно задать количество байт для каждого члена структуры.
DIM>Поправьте если где ошибся.
DIM>Возникли вопросы.
DIM>Где и кем это применяется и для чего? Что это дает еще, кроме того что я указал. Практические примеры.
DIM>Киньте ссылкой на толковую доку и примеры или на название книги.
Вот посмотри здесь
http://rsdn.ru/forum/cpp/395496.aspx
Автор: LaptevVV
Дата: 29.09.03

Я когда-то постил.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Что такое выравнивание структур?
От: andrey.desman  
Дата: 17.10.09 11:06
Оценка:
Здравствуйте, DIMEDROLL, Вы писали:

DIM>Увидел термин в какой то доке, поискал в инете. Из того что понял:

DIM>Это добавление "пустых" данных к обьектам-членам структуры.
DIM>Для чего?
DIM>Что бы ускорить доступ процессора к этим данным.

На x86 да, для ускорения. Лучше даже сказать в немного иной формулировке: "для того, чтобы не допустить падения производительности". Если данные не выровнены, процессор будет выполнять две операции чтения и склеивать две части на краях.
Но шаг в сторону от x86 и чтение невыровненых данных приведет к CPU exception. Например, так обстоит дело на процессорах ARM.

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


Да, выравнивание и дополнение делает компилятор. В общем случае беспокоиться и даже знать об этом не требуется, специально где-то копаться в настройках смысла так же нет.
Все функции/операторы выделения памяти возвращают максимально выровненный указатель. Поэтому структуры/классы дополненные до правильного размера на конце с выровненными членами так же будут выровнены (в т.ч. и массивы таких структур), если расположить их по этому адресу.

DIM>Поправьте если где ошибся.

DIM>Возникли вопросы.
DIM>Где и кем это применяется и для чего? Что это дает еще, кроме того что я указал. Практические примеры.
DIM>Киньте ссылкой на толковую доку и примеры или на название книги.

Х.з. про доки/книги. Но в общем, если хочется иметь меньше "дырок" рекомендуется упорядочивать члены структуры по убыванию размера типа данных. Пример:
#include <iostream>

#define OFFSET_OF(s, m) (int)(( &((s *)0)->m ))

// дырки после каждого char
typedef struct {
   char a1[3];
   int a2;
   char a3;
   int a4;
   char a5;
   int a6[3];
} struct1;

// только три байта в конце не используются
typedef struct {
   int a1;
   int a2;
   int a3[3];
   char a4[3];
   char a5;
   char a6;
} struct2;

int main(void)
{
    std::cout << "struct1: " << sizeof(struct1) << std::endl;
    std::cout << OFFSET_OF(struct1, a1) << std::endl <<
                 OFFSET_OF(struct1, a2) << std::endl <<
                 OFFSET_OF(struct1, a3) << std::endl <<
                 OFFSET_OF(struct1, a4) << std::endl <<
                 OFFSET_OF(struct1, a5) << std::endl <<
                 OFFSET_OF(struct1, a6) << std::endl;

    std::cout << "struct2: " << sizeof(struct2) << std::endl;
    std::cout << OFFSET_OF(struct2, a1) << std::endl <<
                 OFFSET_OF(struct2, a2) << std::endl <<
                 OFFSET_OF(struct2, a3) << std::endl <<
                 OFFSET_OF(struct2, a4) << std::endl <<
                 OFFSET_OF(struct2, a5) << std::endl <<
                 OFFSET_OF(struct2, a6) << std::endl;
    return 0;
}


Вывод:
struct1: 32
0
4
8
12
16
20
struct2: 28
0
4
8
20
23
24
Re: Что такое выравнивание структур?
От: andrey.desman  
Дата: 17.10.09 11:24
Оценка: +1 -1
Здравствуйте, DIMEDROLL, Вы писали:

DIM>Киньте ссылкой на толковую доку и примеры или на название книги.


Да, наверное стоит почитать Техника оптимизации программ &mdash; эффективное использование памяти небезызвестного Криса Касперски aka мыщъх.
Re[2]: Что такое выравнивание структур?
От: ДимДимыч Украина http://klug.org.ua
Дата: 17.10.09 19:20
Оценка: +2
Здравствуйте, andrey.desman, Вы писали:

AD>Но шаг в сторону от x86 и чтение невыровненых данных приведет к CPU exception. Например, так обстоит дело на процессорах ARM.


Более того, на x86 тоже можно установить флаг процессора, при котором невыравненное обращение будет приводить к исключению.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re: Что такое выравнивание структур?
От: Erop Россия  
Дата: 17.10.09 19:20
Оценка:
Здравствуйте, DIMEDROLL, Вы писали:

DIM>Киньте ссылкой на толковую доку и примеры или на название книги.


Вот тут
Автор: Erop
Дата: 28.10.05
было обсуждение.
Нужно это для того, чтобы позволить процессору обращаться к выровненным данным.
В зависимости от платформы обращение к невыровненным данным чревато либо тормозами, либо вообще аппаратными ошибками.
Ну а используют это все, кто программирует на С/С++. Просто некоторые делают это осознанно, а некоторые просто потому, что компилятор делает это незаметно для них
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Что такое выравнивание структур?
От: мыщъх США http://nezumi-lab.org
Дата: 17.10.09 19:36
Оценка: 1 (1)
Здравствуйте, DIMEDROLL, Вы писали:

DIM>Увидел термин в какой то доке, поискал в инете. Из того что понял:

DIM>Это добавление "пустых" данных к обьектам-членам структуры.
незначащих байт к концу пред. элемента, чтобы следующий располагался по "красивому" адресу. по какому именно — зависит от кучи факторов. это нигде недокументированно и отдано на растерзание разработчикам компилятора.

DIM>Для чего?

DIM>Что бы ускорить доступ процессора к этим данным.
некоторые ЦП вообще не могут обращаться к двойным словам, если они лежат по адресу не кратному 4х. у x86 при доступе к невыровненным данным _может_ наблюдаться некоторое замедление, однако, кратность выравнения у них равна размеру кэш-линейки L1. если данные находятся в двух кэш линейках сразу, то мы можем получить тормоза, а можем и не получить, т.к. у пней куча всего понапихано. скажем, если данные находятся в специальной очереди на запись и не представлены в кэше, то понятие "адреса" к ним уже неприменимо. короче, если говорить проще, то разработчики x86 пытаются оптимизировать доступ к данным, перескающим кэш-линейки и у них это неплохо получается. скорость чтения ячейки *(p) и *((int*)p) *((int*)((char*)p+1)) в общем случае одинаково, что легко проверить экспериментально.

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

политика выравнивания, к сожалению, не настраивается. байты выравниваются по своему (обычно никак не выравниваются), дв. слова выравниваются по своему. ну и вообще там много чего выравнивается по своему.

DIM>Где и кем это применяется и для чего? Что это дает еще, кроме того что я указал.

головную боль. если ты собираешь проект двумя компиляторами то это песец какой-то. самый яркий пример, твоя прога на багдаде, а к ней пытаются прицепить плагин на ms vc. если они будут использовать структуры, то их компилятор скорее всего разместит их в памяти по другому и программа ес-но рухнет с треском.

решение: отключать выравнивание структур ключами компиляции или прагамами (но прагмы не стандартизованы, ключи тоже у всех разные).
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[2]: Что такое выравнивание структур?
От: мыщъх США http://nezumi-lab.org
Дата: 17.10.09 19:47
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Здравствуйте, DIMEDROLL, Вы писали:



AD>На x86 да, для ускорения. Лучше даже сказать в немного иной формулировке: "для того, чтобы не допустить падения производительности". Если данные не выровнены, процессор будет выполнять две операции чтения и склеивать две части на краях.

при чтении из кэша операции склейки занимают столько же времени, сколько и без них. не из кэша все равно не прочитаешь, т.к. читается вся строка за раз. правда, тут есть одна тонкость. допустим у нас есть четыре двойных слова A B C D, расположенных в памяти последовательно. если они выровнеы, то за одну итерацию мы можем прочитать A и записать B. а вот если не выровнены — то фигушки. это потому что к кэш-контроллера два порта на чтение и запись, а каждая кэш-линейка это набор 32-разрядных ячеек. если же мы читаем две половинки ячеек, то мы как бы ничего не теряем (скорость не падает), но зато не можем одновременно с этим записать туда что-то еще. кажется, что мы теряем производительность, если в нашем алгоритма чтение чередуются с записью, ну что-то типа a[i] = a[i+1], i+=2; но это не совсем так. тут все зависит от наличия данных в кэше, кол-ва записей и еще черт знает чего. то есть гарантированной "победы" выравнивание не дает, но вот гарантированно увеличивает размер данных со всеми вытекающими из.

AD>Да, выравнивание и дополнение делает компилятор. В общем случае беспокоиться и даже знать об этом не требуется, специально где-то копаться в настройках смысла так же нет.

беспокоиться об этом надо если в проекте задейстовано более одного компилятора.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[3]: Что такое выравнивание структур?
От: мыщъх США http://nezumi-lab.org
Дата: 17.10.09 19:49
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, andrey.desman, Вы писали:


AD>>Но шаг в сторону от x86 и чтение невыровненых данных приведет к CPU exception. Например, так обстоит дело на процессорах ARM.


ДД>Более того, на x86 тоже можно установить флаг процессора, при котором невыравненное обращение будет приводить к исключению.

но только не для целочисленки.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re: Что такое выравнивание структур?
От: gear nuke  
Дата: 19.10.09 15:10
Оценка:
Здравствуйте, DIMEDROLL, Вы писали:

DIM>Увидел термин в какой то доке, поискал в инете. Из того что понял:

DIM>Это добавление "пустых" данных к обьектам-членам структуры.
DIM>Для чего?
DIM>Что бы ускорить доступ процессора к этим данным.

Да

Misaligned data access can incur significant performance penalties. This is particularly
true for cache line splits. The size of a cache line is 64 bytes in the Pentium 4 and
other recent Intel processors, including processors based on Intel Core microarchitecture.

An access to data unaligned on 64-byte boundary leads to two memory accesses and
requires several ?ops to be executed (instead of one). Accesses that span 64-byte
boundaries are likely to incur a large performance penalty, the cost of each stall
generally are greater on machines with longer pipelines.


Assembly/Compiler Coding Rule 45. (H impact, H generality) Align data on
natural operand size address boundaries. If the data will be accessed with vector
instruction loads and stores, align the data on 16-byte boundaries.
For best performance, align data as follows:
• Align 8-bit data at any address.
• Align 16-bit data to be contained within an aligned 4-byte word.
• Align 32-bit data so that its base address is a multiple of four.
• Align 64-bit data so that its base address is a multiple of eight.
• Align 80-bit data so that its base address is a multiple of sixteen.
• Align 128-bit data so that its base address is a multiple of sixteen.
A 64-byte or greater data structure or array should be aligned so that its base
address is a multiple of 64. Sorting data in decreasing size order is one heuristic for
assisting with natural alignment. As long as 16-byte boundaries (and cache lines) are
never crossed, natural alignment is not strictly necessary (though it is an easy way to
enforce this).


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


Да, у каждого компилятора должно быть что-то вроде #pragma pack

DIM>Поправьте если где ошибся.

DIM>Возникли вопросы.
DIM>Где и кем это применяется и для чего? Что это дает еще, кроме того что я указал. Практические примеры.
DIM>Киньте ссылкой на толковую доку и примеры или на название книги.

Intel 64 and IA-32 Architectures Optimization Reference Manual и аналог от AMD

И наверняка есть что почитать у Agner Fog.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Что такое выравнивание структур?
От: gear nuke  
Дата: 19.10.09 15:26
Оценка: +1
Здравствуйте, мыщъх, Вы писали:

М>но только не для целочисленки.


Ты путаешь #GF для SIMD-данных с замаскированным в винде #AF.

AC (bit 18) Alignment check flag — Set this flag and the AM bit in the CR0 register to enable alignment checking of memory references; clear the AC flag and/or the AM bit to disable alignment checking.

.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: Что такое выравнивание структур?
От: saproj  
Дата: 20.10.09 11:10
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Более того, на x86 тоже можно установить флаг процессора, при котором невыравненное обращение будет приводить к исключению.


offtopic:
К сожалению, это только на 3-м кольце и под Windows надо еще отключать автоматическую обработку этого исключения.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.