выравнивание памяти классов

Я работаю над менеджером памяти с помощью книги Архитектура игрового движка.
Сейчас я читаю о выравнивании памяти (в книге и в Интернете) и не уверен, как правильно использовать выравнивание для классов. Я понимаю концепцию выравнивания памяти (например, 4-байтовый блок данных должен быть расположен по адресу, оканчивающемуся на 0x0, 0x4, 0x8 или 0xC), но на allocateAligned()-функция в книге — это комментарий, который говорит, что выравнивание должно быть степенью двойки. Если у меня есть класс, который имеет два intИ один char, sizeof(classs) говорит мне, что класс имеет размер 12 байт. Итак, вы бы передали 32 как выравнивание? Не будет ли это пустой тратой памяти и может привести к фрагментации?
Мой вопрос: как правильно выровнять классы, не могли бы вы объяснить мне это более подробно (что произойдет, если вы хотите выровнять большие фрагменты данных, например, 121 байт), и имеет ли смысл выравнивать более крупные фрагменты (потому что процессор извлекает только 8 байтов за один вызов, если я правильно информирован)?

6

Решение

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

Не менее важно то, что выравнивание типа может быть меньше чем размер типа.

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

Вот почему ваш тип класса имеет два байта заполнения: 12 делится на четыре равномерно, а 10 — нет. Если бы у вашего класса не было заполнения, его размер был бы всего 10 байтов, а в массиве элементов половина объектов была бы выровнена.

7

Другие решения

Выравнивание типа может быть меньше, но не больше его размера. В типичной 32-битной реализации ваш

struct X {
int a;
int b;
char c;
};

скорее всего sizeof(X) == 12 а также alignof(X) == 4, Очевидно, вы не можете иметь X каждые четыре байта, потому что они будут перекрываться, но выравнивание означает, что 0x1000, 0x1004, 0x1008, а также 0x100c все потенциальные места вы может быть начать X,

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

2

По вопросам рекламы [email protected]