在mmx,sse优化的时候经常要求内存按8,16字节对齐。但是默认的编译器一般都是8字节对齐。所以需要在分配内存的时候,能按16或则其他字节对齐。
以下是从xvid工程中找到的任意字节对齐的内存分配函数。
/**/
/*****************************************************************************
* align_malloc
*
* This function allocates 'size' bytes (usable by the user) on the heap and
* takes care of the requested 'alignment'.
* In order to align the allocated memory block, the xvid_malloc allocates
* 'size' bytes + 'alignment' bytes. So try to keep alignment very small
* when allocating small pieces of memory.
*
* NB : a block allocated by xvid_malloc _must_ be freed with xvid_free
* (the libc free will return an error)
*
* Returned value : - NULL on error
* - Pointer to the allocated aligned block
*
****************************************************************************/
void * align_malloc(unsigned int size, unsigned int alignment)
... {
unsigned char * mem_ptr;
unsigned char * tmp;
if(!alignment) alignment=4; //至少按4对齐
/**//* Allocate the required size memory + alignment so we
* can realign the data if necessary */
if ((tmp = (unsigned char *) malloc(size + alignment)) != NULL) ...{
/**//* Align the tmp pointer */
mem_ptr =
(unsigned char *) ((unsigned int) (tmp + alignment - 1) &
(~(unsigned int) (alignment - 1)));
/**//* Special case where malloc have already satisfied the alignment
* We must add alignment to mem_ptr because we must store
* (mem_ptr - tmp) in *(mem_ptr-1)
* If we do not add alignment to mem_ptr then *(mem_ptr-1) points
* to a forbidden memory space */
if (mem_ptr == tmp)
mem_ptr += alignment;
/**//* (mem_ptr - tmp) is stored in *(mem_ptr-1) so we are able to retrieve
* the real malloc block allocated and free it in xvid_free */
*(mem_ptr - 1) = (unsigned char) (mem_ptr - tmp);
//PRT("Alloc mem addr: 0x%08x, size:% 8d, file:%s <line:%d>, ", tmp, size, file, line);
/**//* Return the aligned pointer */
return ((void *)mem_ptr);
}
return(NULL);
}
/**/ /*****************************************************************************
* align_free
*
* Free a previously 'xvid_malloc' allocated block. Does not free NULL
* references.
*
* Returned value : None.
*
****************************************************************************/
void align_free( void * mem_ptr)
... {
unsigned char *ptr;
if (mem_ptr == NULL)
return;
/**//* Aligned pointer */
ptr = ( unsigned char *)mem_ptr;
/**//* *(ptr - 1) holds the offset to the real allocated block
* we sub that offset os we free the real pointer */
ptr -= *(ptr - 1);
/**//* Free the memory */
free(ptr);
}
* align_malloc
*
* This function allocates 'size' bytes (usable by the user) on the heap and
* takes care of the requested 'alignment'.
* In order to align the allocated memory block, the xvid_malloc allocates
* 'size' bytes + 'alignment' bytes. So try to keep alignment very small
* when allocating small pieces of memory.
*
* NB : a block allocated by xvid_malloc _must_ be freed with xvid_free
* (the libc free will return an error)
*
* Returned value : - NULL on error
* - Pointer to the allocated aligned block
*
****************************************************************************/
void * align_malloc(unsigned int size, unsigned int alignment)
... {
unsigned char * mem_ptr;
unsigned char * tmp;
if(!alignment) alignment=4; //至少按4对齐
/**//* Allocate the required size memory + alignment so we
* can realign the data if necessary */
if ((tmp = (unsigned char *) malloc(size + alignment)) != NULL) ...{
/**//* Align the tmp pointer */
mem_ptr =
(unsigned char *) ((unsigned int) (tmp + alignment - 1) &
(~(unsigned int) (alignment - 1)));
/**//* Special case where malloc have already satisfied the alignment
* We must add alignment to mem_ptr because we must store
* (mem_ptr - tmp) in *(mem_ptr-1)
* If we do not add alignment to mem_ptr then *(mem_ptr-1) points
* to a forbidden memory space */
if (mem_ptr == tmp)
mem_ptr += alignment;
/**//* (mem_ptr - tmp) is stored in *(mem_ptr-1) so we are able to retrieve
* the real malloc block allocated and free it in xvid_free */
*(mem_ptr - 1) = (unsigned char) (mem_ptr - tmp);
//PRT("Alloc mem addr: 0x%08x, size:% 8d, file:%s <line:%d>, ", tmp, size, file, line);
/**//* Return the aligned pointer */
return ((void *)mem_ptr);
}
return(NULL);
}
/**/ /*****************************************************************************
* align_free
*
* Free a previously 'xvid_malloc' allocated block. Does not free NULL
* references.
*
* Returned value : None.
*
****************************************************************************/
void align_free( void * mem_ptr)
... {
unsigned char *ptr;
if (mem_ptr == NULL)
return;
/**//* Aligned pointer */
ptr = ( unsigned char *)mem_ptr;
/**//* *(ptr - 1) holds the offset to the real allocated block
* we sub that offset os we free the real pointer */
ptr -= *(ptr - 1);
/**//* Free the memory */
free(ptr);
}