内存对齐指令详解(posix_memalign)
生活随笔
收集整理的這篇文章主要介紹了
内存对齐指令详解(posix_memalign)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
posix_memalign
opencv中的內存對齊函數源碼
posix_memalign
預對齊內存的分配
在大多數情況下,編譯器和C庫透明地幫你處理對齊問題。POSIX 標明了通過malloc( ),?calloc( ), 和?realloc( )?返回的地址對于任何的C類型來說都是對齊的。在Linux中,這些函數返回的地址在32位系統是以8字節為邊界對齊,在64位系統是以16字節為邊界對齊的。有時候,對于更大的邊界,例如頁面,程序員需要動態的對齊。雖然動機是多種多樣的,但最常見的是直接塊I/O的緩存的對齊或者其它的軟件對硬件的交互,因此,POSIX 1003.1d提供一個叫做posix_memalign( )的函數:
/* one or the other -- either suffices */ #define _XOPEN_SOURCE 600 #define _GNU_SOURCE #include <stdlib.h> int posix_memalign (void **memptr,size_t alignment,size_t size);* See http://perens.com/FreeSoftware/ElectricFence/ and http://valgrind.org, respectively. 調用posix_memalign( )成功時會返回size字節的動態內存,并且這塊內存的地址是alignment的倍數。參數alignment必須是2的冪,還是void指針的大小的倍數。返回的內存塊的地址放在了memptr里面,函數返回值是0.調用失敗時,沒有內存會被分配,memptr的值沒有被定義,返回如下錯誤碼之一: EINVAL 參數不是2的冪,或者不是void指針的倍數。 ENOMEM 沒有足夠的內存去滿足函數的請求。 要注意的是,對于這個函數,errno不會被設置,只能通過返回值得到。由posix_memalign( )獲得的內存通過free( )釋放。用法很簡單: char *buf; int ret; /* allocate 1 KB along a 256-byte boundary */ ret = posix_memalign (&buf, 256, 1024); if (ret) {fprintf (stderr, "posix_memalign: %s\n",strerror (ret));return -1; } /* use 'buf'... */ free (buf);與對齊有關的問題的范圍要超過標準類型的自然對齊和動態存儲器地分配。例如,非標準和復雜的類型比標準類型有更復雜的要求。另外,對對齊的關注在給指向不同類型的指針賦值和使用強轉時顯得加倍的重要。非標準類型。非標準和復雜的數據類型的對齊比簡單的自然對齊有著更多的要求。這里四個有很有用的方法: ?一個結構的對齊要求是和它的成員中最大的那個類型一樣的。例如,一個結構中最大的是以4字節對齊的32bit的整形,那么這個結構至少以4字節對齊。 ?結構也引入了填充的需要,用來保證每一個成員都符合自己的對齊要求。所以,如果一個char (可能以1字節對齊)后跟著一個int (可能以4字節對齊),編譯器會自動地插入3個字節作為填充來保證int以4字節對齊。 程序員有時候排列結構里面的成員-例如,以大小來遞減-來是使用作填充的垃圾空間最少。GCC的選項- Wpadded能對這些努力有幫助,因為它使得在編譯器偷偷插入填充時產生警告。 ?一個聯合的對齊和聯合里最大的類型一樣。 ?一個數組的對齊和數組里的元素一樣。所以,數組的對齊并不比單單的一個成員嚴格,這樣能使數組里面的所有成員都是自然對齊的。其他平臺的內存對齊函數雷同:如win32系統函數:_aligned_malloc(size,?alignment),android系統函數:memalign(alignment,?size)
opencv中的內存對齊函數源碼(ncnn寫法也一樣,應該是參考opencv)
template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n = (int)sizeof(_Tp)) {assert((n & (n - 1)) == 0); // n is a power of 2return (_Tp*)(((size_t)ptr + n - 1) & -n); }void* fastMalloc(size_t size) {unsigned char* udata = (unsigned char*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);if (udata){unsigned char** adata = alignPtr((unsigned char**)udata + 1, CV_MALLOC_ALIGN);/*保存原始的內存地址,adata是對齊后的地址,若直接釋放這個地址,則會產生內存泄露。malloc得到的指針地址保存在adata的前一塊區域內*/adata[-1] = udata;return adata;}return NULL; }void fastFree(void* ptr) {if (ptr){unsigned char* udata = ((unsigned char**)ptr)[-1];assert(udata < (unsigned char*)ptr &&((unsigned char*)ptr - udata) <= (std::ptrdiff_t)(sizeof(void*) + CV_MALLOC_ALIGN));free(udata);} }CV_MALLOC_ALIGN為需要對齊的bit數?
?
總結
以上是生活随笔為你收集整理的内存对齐指令详解(posix_memalign)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 代码执行流水之循环展开优化
- 下一篇: 岛屿数量—leetcode200