Вопрос

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

Предположим, что у меня есть пул памяти, который выдает блоки памяти фиксированного размера, в момент создания пула памяти я malloc((размер)*(количество блоков)).Если то, что выделяется, является объектами, а размер определяется оператором sizeof, выравнивание не должно вызывать беспокойства, но если размер неравномерен (по какой-либо причине ему нужны блоки по 100 байт), то, когда я разделяю фрагмент, предоставленный malloc, я получаю невыровненные указатели.Мой вопрос в том, должен ли я всегда выравнивать блоки по некоторой границе, и если да, то по какой?

Это было полезно?

Решение

X86 будет работать без выравнивания, но при выравнивании данных производительность выше. Выравнивание для type обычно имеет размер sizeof ( type ), максимум до 16 (байтов).

Я написал эту глупую тестовую программу просто для уверенности (предполагая, что malloc знает, что делает), и она возвращает 16 на моей коробке amd64. Возвращает 8 при компиляции в 32-битном режиме:

#include <stdlib.h>
#include <stdio.h>

int main() {
    int i;
    unsigned long used_bits = 0, alignment;

    for (i = 0; i < 1000; ++i) {
        used_bits |= (unsigned long)malloc(1);   /* common sizes */
        used_bits |= (unsigned long)malloc(2);   
        used_bits |= (unsigned long)malloc(4);
        used_bits |= (unsigned long)malloc(8);
        used_bits |= (unsigned long)malloc(16);
        used_bits |= (unsigned long)malloc(437); /* random number */
    }

    alignment = 1;
    while (!(used_bits & alignment)) {
        alignment <<= 1;
    }

    printf("Alignment is: %lu\n", alignment);
    return 0;
}

Другие советы

Правильное выравнивание, по крайней мере, полезно (с точки зрения производительности) в большинстве реализаций x86 (и какое-то выравнивание фактически обязательно в других архитектурах).Вы могли бы запросить (как это делает calloc) пару аргументов, размер элементов в байтах и количество элементов, а не только один (размер в байтах, как это делает malloc);затем вы можете внутренне выровнять (путем округления размеров блоков) до следующей степени, превышающей размер элемента на 2 (но переключитесь на значения, кратные 16 байтам выше 16, не продолжайте удваивать вечно, как рекомендует и объясняет @derobert!-).Таким образом, если вызывающей стороне просто нужно N байт без какого-либо выравнивания или заполнения, они всегда могут запросить N элементов по 1 байту каждый (точно так же, как с calloc и по той же причине;-).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top