gpt4 book ai didi

c - 为什么在尝试在 C 中分配新内存时需要对齐

转载 作者:太空宇宙 更新时间:2023-11-04 03:52:53 25 4
gpt4 key购买 nike

现在在看C的接口(interface)和实现,第四张图是内存管理,上面说对齐确保任何类型的数据都可以存储在Mem_alloc函数返回的 block 中。这句话怎么理解?是内存管理时需要对齐吗?

对齐代码如下:

union align {
#ifdef MAXALIGN
char pad[MAXALIGN];
#else
int i;
long l;
long *lp;
void *p;
void (*fp)(void);
float f;
double d;
long double ld;
#endif
void *Mem_alloc(long nbytes, const char *file, int line){
struct descriptor *bp;
void *ptr;
assert(nbytes > 0);
nbytes = ((nbytes + sizeof (union align) - 1)/
(sizeof (union align)))*(sizeof (union align));
for (bp = freelist.free; bp; bp = bp->free) {
if (bp->size > nbytes) {
bp->size -= nbytes;
ptr = (char *)bp->ptr + bp->size;
if ((bp = dalloc(ptr, nbytes, file, line)) != NULL) {
unsigned h = hash(ptr, htab);
bp->link = htab[h];
htab[h] = bp;
return ptr;
} else
{
if (file == NULL)
RAISE(Mem_Failed);
else
Except_raise(&Mem_Failed, file, line);
}
}
if (bp == &freelist) {
struct descriptor *newptr;
if ((ptr = malloc(nbytes + NALLOC)) == NULL
|| (newptr = dalloc(ptr, nbytes + NALLOC,
__FILE__, __LINE__)) == NULL)
{
if (file == NULL)
RAISE(Mem_Failed);
else
Except_raise(&Mem_Failed, file, line);
}
newptr->free = freelist.free;
freelist.free = newptr;
}
}
assert(0);
return NULL;
}
};

void *Mem_resize(void *ptr, long nbytes,
const char *file, int line) {
struct descriptor *bp;
void *newptr;
assert(ptr);
assert(nbytes > 0);
if (((unsigned long)ptr)%(sizeof (union align)) != 0
|| (bp = find(ptr)) == NULL || bp->free)
Except_raise(&Assert_Failed, file, line);
newptr = Mem_alloc(nbytes, file, line);
memcpy(newptr, ptr,
nbytes < bp->size ? nbytes : bp->size);
Mem_free(ptr, file, line);
return newptr;
}

我如何理解这些代码?为什么调整空间大小时需要 if (((unsigned long)ptr)%(sizeof (union align)) != 0?

最佳答案

CPU 在处理数据方面存在局限性。例如,指针通常必须为 32 位 CPU 对齐 4 字节,为 64 位 CPU 对齐 8 字节。此外,在允许的情况下,在非对齐边界上加载和存储数据可能会导致性能下降。例如,一个 CPU 可能能够从一个奇数地址加载,但它需要两倍的周期。这通常是因为存储器硬件针对在 4、8 或 16 字节边界上抓取数据进行了优化,并且必须在一个周期中加载数据字的低位部分,然后在下一个周期中加载高位部分。

因此,在实现编译器时,您希望它能够在具有这些对齐需求的 CPU 上正常运行。

See here以 Intel 的 IA-64 对齐要求为例:

  • Align 8-bit data at any address
  • Align 16-bit data to be contained within an aligned four-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

关于c - 为什么在尝试在 C 中分配新内存时需要对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19372627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com