What is the purpose of aligning pointer position C ++

Now I am reading the source code of OPENCV - open source computer libraries. I am confused by this function:

#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

is used to allocate memory for a pointer that calls a function malloc

and then alignPtr

. I can't figure out why alignPtr

is it called after memory allocation? My basic understanding is that it is much faster for a machine to find a pointer. Can some links to this problem be found on the Internet? Is it still necessary for a modern computer to perform this operation? Any ideas would be appreciated.

+3


source to share


2 answers


Some platforms require certain data types to be mapped at specific byte boundaries (for example: - some compilers require pointers to be stored at 4 byte boundaries).

This is called alignment and requires additional padding inside and possibly at the end of the object's data.

The compiler may break if they do not find the correct alignment, or there may be a performance bottleneck when reading this data (since it would be necessary to read two blocks to get the same data).

CHANGED WITH REGARD TO THE COMMENT: -

A program's request for memory is usually handled by a memory allocator. One such memory allocator fixed-size allocator

. Initial allocation blocks of a fixed size of the specified size, even if the requested memory is less than a specified size. So with this background, let me try to explain what's going on here: -



uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);

      

This will allocate an amount of memory equal to memory_requested + random_size

. There random_size

fills the gap to match the size specified for the placement of a fixed scheme.

uchar** adata = alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);

      

This tries to align the pointer with a specific border as described above.

+1


source


It allocates a block a little more than it was requested.

Then it sets adata

to the address of the next correctly allocated byte (add one byte, then round to the next correctly aligned address).

Then it saves the original pointer before the new address. I guess this is later used to free the originally allocated block.



And then we return the new address.

This only makes sense if it CV_MALLOC_ALIGN

is a stricter alignment than malloc

guaranteed - perhaps a cache line?

+1


source







All Articles