стоит ли выравнивать переменные? - PullRequest
0 голосов
/ 10 октября 2018

Я читал статьи о преимуществах выравнивания переменных.Например, в C / C ++ переменные в стеке могут быть выровнены с помощью __attribute__( ( aligned ( .. ) ) ), а память кучи может быть выровнена с помощью std::align.Если выравнивание памяти так важно, почему не все компиляторы делают это автоматически по умолчанию?По крайней мере, я ожидал флаг компилятора gcc / g ++ для автоматического выравнивания всего.Однако, похоже, что это не так, и люди все еще вручную указывают, что память должна быть выровнена, используя вышеупомянутые способы.Это почему?Стоит ли использовать вышеперечисленные способы выравнивания памяти или есть недостатки?Я ожидаю, что при использовании флагов -O2, -O3 большое выравнивание памяти происходит как способ оптимизации программы.Спасибо.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Все компиляторы делают выравнивание по умолчанию.Просто есть ситуации, когда вам нужно выравнивание не по умолчанию .

По умолчанию для базового типа используется его размер.Выравнивание по умолчанию для типа класса - это максимальное выравнивание всех его баз и членов данных.

Многие реализации поддерживают (как расширение языка) атрибут [[packed]], который уменьшает выравниваниетипа до 1, исключая заполнение между членами данных в типах классов.Такие значения обычно отправляются и принимаются как char[], по сравнению с memcmp и т. Д.

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

0 голосов
/ 10 октября 2018

Это зависит от того, что вы делаете.Если вы занимаетесь тяжелой математикой с векторами или массивами, вы сильно выиграете, если будете использовать пользовательское выравнивание.Например, с avx-512, когда вы выравниваете свои данные с 64 байтами, вы можете напрямую загружать ваши данные блоками по 8 дублей в регистры zmmm с помощью _mm512_load_pd, применять к ним SIMD инструкции и сохранять их с помощью _mm512_stream_pd.В противном случае, если вы не будете выполнять тяжелые векторизованные вычисления, вы просто потеряете память, на что указывает drescherjm в его комментарии .

.11 вы можете использовать alignas спецификатор , например, вы можете определить выровненный массив как:

template <typename T, size_t N, size_t Alignment = 64>
struct alignas(Alignment) AlignedArray : std::array<T, N> {};

И, начиная с C ++ 17, вы можете использовать std::aligned_alloc для динамически выровненных распределений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...