我想了解memalign()
和posix_memalign()
有什麼功能。閱讀可用的文檔沒有幫助。posix_memalign/memalign做什麼
有人能幫我理解它是如何工作的,它用於什麼?或者,也許提供一個使用示例?我想知道linux內存是如何工作的,我需要編寫自己的簡單內存池(低碎片堆)。
我想了解memalign()
和posix_memalign()
有什麼功能。閱讀可用的文檔沒有幫助。posix_memalign/memalign做什麼
有人能幫我理解它是如何工作的,它用於什麼?或者,也許提供一個使用示例?我想知道linux內存是如何工作的,我需要編寫自己的簡單內存池(低碎片堆)。
而malloc
爲您提供了一個可以進行任何對齊的內存塊(唯一的要求是它必須與實現支持的最大基元類型對齊),posix_memalign
爲您提供了一塊保證有內存的塊請求的路線。
因此, posix_memalign(&p, 32, 128)
將是一個128字節的內存塊,其起始地址保證是32的倍數。
這對於需要內存的各種低級操作(如使用SSE指令或DMA)很有用服從特定的對齊。
'malloc'的結果不具有「任何」對齊。它保證適合系統上任何本地類型(int,long,double,structs等)。你認爲大對齊可能用於特殊目的是正確的,但對於絕大多數應用程序來說,malloc的結果是一致的。 –
@John:你是對的;讓我改變我的措辭... –
有沒有很好的理由更喜歡'posix_memalign'而不是'mmap',它分配對齊的內存? –
它是如何工作的,取決於實施。該函數的目的是給你一個n字節對齊的內存塊(塊的起始地址是n的乘法)。
malloc
總是返回設置爲任何基本類型所需的最大對齊方式的內存。這允許malloc
'內存存儲您可能需要的任何類型。我對posix_memalign
的描述的理解是,它返回一個內存位置,其地址將是您指定爲對齊的任意倍數。
我不知道這會在編寫自定義內存池時有多麼有用,但我已經提供了一個如何實現這個功能的示例。與我的例子不同的是,任何分配爲malloc_aligned
的東西都必須用free_aligned
釋放;但是,使用posix_memalign
您可以使用free
。
#include <stdlib.h>
#include <stdio.h>
void *malloc_aligned(size_t alignment, size_t bytes)
{
// we need to allocate enough storage for the requested bytes, some
// book-keeping (to store the location returned by malloc) and some extra
// padding to allow us to find an aligned byte. im not entirely sure if
// 2 * alignment is enough here, its just a guess.
const size_t total_size = bytes + (2 * alignment) + sizeof(size_t);
// use malloc to allocate the memory.
char *data = malloc(sizeof(char) * total_size);
if (data)
{
// store the original start of the malloc'd data.
const void * const data_start = data;
// dedicate enough space to the book-keeping.
data += sizeof(size_t);
// find a memory location with correct alignment. the alignment minus
// the remainder of this mod operation is how many bytes forward we need
// to move to find an aligned byte.
const size_t offset = alignment - (((size_t)data) % alignment);
// set data to the aligned memory.
data += offset;
// write the book-keeping.
size_t *book_keeping = (size_t*)(data - sizeof(size_t));
*book_keeping = (size_t)data_start;
}
return data;
}
void free_aligned(void *raw_data)
{
if (raw_data)
{
char *data = raw_data;
// we have to assume this memory was allocated with malloc_aligned.
// this means the sizeof(size_t) bytes before data are the book-keeping
// which points to the location we need to pass to free.
data -= sizeof(size_t);
// set data to the location stored in book-keeping.
data = (char*)(*((size_t*)data));
// free the memory.
free(data);
}
}
int main()
{
char *ptr = malloc_aligned(7, 100);
printf("is 5 byte aligned = %s\n", (((size_t)ptr) % 5) ? "no" : "yes");
printf("is 7 byte aligned = %s\n", (((size_t)ptr) % 7) ? "no" : "yes");
free_aligned(ptr);
return 0;
}
感謝您的支持!非常有用的一段代碼作爲memalign的替代品,這在某種程度上仍然是從mingw中遺漏的。 – Bart
除了奧利的回答,我想指出一個更重要的問題。
在最近的x86體系結構中,緩存行是可以從內存獲取到緩存的最小數據量,爲64字節。假設你的結構大小是56字節,你有一大堆數組。當查找一個元素時,CPU需要發出2個內存請求(即使它位於緩存行中間,它也可能發出2個請求)。這對性能不利,因爲您必須等待內存,並且使用更多緩存,這最終會導致更高的緩存未命中率。在這種情況下,僅僅使用posix_memalign是不夠的,但是你應該將你的結構填充或壓縮到64字節的邊界。
有40字節的結構是隻是運氣不好:)
Deffault的malloc返回指針是多重的8,它的平均分malloc的內存塊有8個字節,並在每個塊的開始檢查可用內存。有兩個問題的面孔。
較大的塊將浪費更多的內存,但較大的塊幫助C更快地找到空閒塊存儲器。 memalign可以改變這些塊的大小。如果要節省內存,請將塊大小減小到2或4.如果要使應用程序更快,請將塊大小增加到2。
這是錯誤的和令人困惑的。 – jleahy
由於memalign已過時(ref:man page),這裏只介紹malloc()和posix_memalign()之間的區別。 malloc()是8字節對齊的(例如,對於RHEL 32位),但對於posix_memalign(),對齊是用戶可定義的。要知道這個的用法,或許一個很好的例子是使用mprotect()來設置內存屬性。要使用mprotect(),內存指針必須是PAGE對齊的。因此,如果您使用pagesize調用posix_memalign()作爲對齊方式,則返回的指針可以輕鬆地提交給mprotect()以設置可讀寫可執行屬性。 (例如,在將數據複製到內存指針之後,可以將其設置爲只讀屬性以防止它被修改)。 「malloc()」的返回指針不能在這裏使用。
當您說「需要」時,您是在談論一項家庭作業任務還是您對軟件的需求?如果是後者,我很懷疑。標準分配器在大多數負載下都是非常低的碎片。 –