对齐C++指针位置的目的是什么
What's the purpose of align C++ pointer position
我正在阅读计算机视觉开源库OPENCV的源代码。我对这个功能感到困惑:
#define CV_MALLOC_ALIGN 16
void* fastMalloc( size_t size )
{
uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
if(!udata)
return OutOfMemoryError(size);
uchar** adata = alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);
adata[-1] = udata;
return adata;
}
/*!
Aligns pointer by the certain number of bytes
This small inline function aligns the pointer by the certian number of bytes by
shifting it forward by 0 or a positive offset.
*/
template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
{
return (_Tp*)(((size_t)ptr + n-1) & -n);
}
fastMalloc
用于为指针分配内存,调用malloc
函数,然后调用alignPtr
。我不太明白为什么在分配内存后调用alignPtr
?我的基本理解是这样做可以让机器更快地找到指针。可以在互联网上找到有关此问题的一些参考资料吗?对于现代计算机来说,还有必要进行这样的操作吗?任何想法将不胜感激。
一些平台要求某些类型的数据出现在某些字节边界上(例如:- 一些编译器
要求 指针存储在 4 字节边界上 )。
这称为对齐,它需要在对象数据内(可能在对象数据的末尾)进行额外填充。
如果编译器没有找到正确的对齐方式,或者在读取该数据时可能存在性能瓶颈(因为需要读取两个块才能获取相同的数据),编译器可能会中断。
根据评论进行编辑:-
程序的内存请求通常由内存分配器处理。一种这样的内存分配器是 fixed-size allocator
。固定大小分配 return 指定大小的块,即使请求的内存小于该特定大小。所以,在这样的背景下,让我试着解释一下这里发生了什么:-
uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
这将分配等于 memory_requested + random_size
的内存量。这里 random_size
正在填补空白以使其适合为固定分配方案指定的大小。
uchar** adata = alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);
这是在尝试将指针对齐到特定边界,如上所述。
它分配的块比要求的大一点。
然后它将 adata
设置为下一个正确分配字节的地址(添加一个字节,然后四舍五入到下一个正确对齐的地址)。
然后将原来的指针存入新地址之前。我假设这稍后用于释放最初分配的块。
然后我们return新地址。
这只有在 CV_MALLOC_ALIGN
比 malloc
保证更严格的对齐时才有意义 - 也许是缓存行?
我正在阅读计算机视觉开源库OPENCV的源代码。我对这个功能感到困惑:
#define CV_MALLOC_ALIGN 16
void* fastMalloc( size_t size )
{
uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
if(!udata)
return OutOfMemoryError(size);
uchar** adata = alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);
adata[-1] = udata;
return adata;
}
/*!
Aligns pointer by the certain number of bytes
This small inline function aligns the pointer by the certian number of bytes by
shifting it forward by 0 or a positive offset.
*/
template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
{
return (_Tp*)(((size_t)ptr + n-1) & -n);
}
fastMalloc
用于为指针分配内存,调用malloc
函数,然后调用alignPtr
。我不太明白为什么在分配内存后调用alignPtr
?我的基本理解是这样做可以让机器更快地找到指针。可以在互联网上找到有关此问题的一些参考资料吗?对于现代计算机来说,还有必要进行这样的操作吗?任何想法将不胜感激。
一些平台要求某些类型的数据出现在某些字节边界上(例如:- 一些编译器 要求 指针存储在 4 字节边界上 )。
这称为对齐,它需要在对象数据内(可能在对象数据的末尾)进行额外填充。
如果编译器没有找到正确的对齐方式,或者在读取该数据时可能存在性能瓶颈(因为需要读取两个块才能获取相同的数据),编译器可能会中断。
根据评论进行编辑:-
程序的内存请求通常由内存分配器处理。一种这样的内存分配器是 fixed-size allocator
。固定大小分配 return 指定大小的块,即使请求的内存小于该特定大小。所以,在这样的背景下,让我试着解释一下这里发生了什么:-
uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
这将分配等于 memory_requested + random_size
的内存量。这里 random_size
正在填补空白以使其适合为固定分配方案指定的大小。
uchar** adata = alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);
这是在尝试将指针对齐到特定边界,如上所述。
它分配的块比要求的大一点。
然后它将 adata
设置为下一个正确分配字节的地址(添加一个字节,然后四舍五入到下一个正确对齐的地址)。
然后将原来的指针存入新地址之前。我假设这稍后用于释放最初分配的块。
然后我们return新地址。
这只有在 CV_MALLOC_ALIGN
比 malloc
保证更严格的对齐时才有意义 - 也许是缓存行?