Выравнивание структуры в линейном распределителе

#c #memory #alignment

Вопрос:

Я создаю очень простой линейный распределитель для этого класса на x64:

 class Test {
    size_t first[64];    // 512 bytes
    void* second[64];    // 512 bytes
    unsigned char third; // 1 byte
};
 

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

Теперь вот основные черты того, что представляет собой мой линейный распределитель:

 class Allocator {
private:
    Test* memory;
public:
    Allocator(const size_t size) {
        memory = static_cast<Test*>(malloc(sizeof(Test) * size));
    }
    Test* allocate() {
        return memory  ;
    }
};
 

И это хорошо работает!

Однако я вижу, что многие другие простые линейные распределители выравнивают память в allocate функции. Почему они это делают? Сама Test структура уже выровнена.

Кроме того, если вы решите использовать какой-то тип выравнивания, вы бы выровняли память при ее выделении? Или вы бы вернули выровненный указатель в allocate функции? Кроме того, вы бы выровняли его по sizeof(Test) размеру платформы или по WORD размеру платформы?

Ответ №1:

  1. many other simple linear allocators align the memory in the allocate function. Why do they do this? Они делают это, если им нужно выровнять по-другому, например, 16 или 32 байта (для использования с AVX).
  2. if you do align the newly allocated memory, would you align the memory when you allocate it? Or would you align it when you return the memory block? Вы не можете выровнять уже выделенную память.
  3. Also, would you align it to the sizeof(Test), or the platform's WORD size? Зависит от ТОГО, ПОЧЕМУ вы настраиваетесь.

Комментарии:

1. Для #2 я имел в виду, например , вызов aligned_alloc для выделения вместо malloc , а затем в allocate функции вы вручную выровняете память для возврата.

2. Кроме того, я настраиваюсь на производительность, так как буду выполнять много распределений.