是否可以(在任何合理的操作系統上,最好是Linux上)通過修改頁表而不是實際移動任何數據來交換兩個內存頁的內容?可以通過修改頁面表來移動內存頁面嗎?
動機是一種密集的矩陣轉置。如果數據被頁面大小阻塞,則可以在頁面內調換數據(適合緩存),然後交換頁面以將塊移動到最終位置。一個大的矩陣會有很多頁面移動,所以希望刷新TLB不會造成麻煩。
是否可以(在任何合理的操作系統上,最好是Linux上)通過修改頁表而不是實際移動任何數據來交換兩個內存頁的內容?可以通過修改頁面表來移動內存頁面嗎?
動機是一種密集的矩陣轉置。如果數據被頁面大小阻塞,則可以在頁面內調換數據(適合緩存),然後交換頁面以將塊移動到最終位置。一個大的矩陣會有很多頁面移動,所以希望刷新TLB不會造成麻煩。
我認爲內存映射文件可能會訣竅,但我認爲我從來沒有嘗試過這一點。使用mmap與MAP_ANONYMOUS映射到純虛擬地址(不支持物理文件)。然後,您可以將您的'文件'重新映射到VA的各個區域,以實現零拷貝語義。在Windows中,您將使用MapViewOfFile以及使用CreateMapOfFile(INVALID_HANDLE_VALUE,...)創建的文件映射句柄,但是注意比在NT上無法控制重新映射的目標(即,新映射的VA地址是輸出函數調用的),並且在Linux上,期望的地址被認爲是提示。
如果這不起作用,那麼你可能需要在內核中創建一個內存管理器模塊,這對任何實際項目都是不可行的。
理論上肯定。實際上,我認爲認爲您可以使用mmap()以這種方式移動系統V風格的共享內存塊。
#include <stdio.h>
#include <string.h>
#define __USE_GNU
#include <unistd.h>
#include <sys/mman.h>
int main() {
int PAGE_SIZE = getpagesize();
char* m = NULL;
void* temp;
printf("page size = %d\n", PAGE_SIZE);
m = (char*)mmap(0, PAGE_SIZE*3, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
temp = m+PAGE_SIZE*2;
memset(m, '0', PAGE_SIZE);
memset(m+PAGE_SIZE, '1', PAGE_SIZE);
printf("before %c %c\n", m[0], m[PAGE_SIZE]);
mremap(m + PAGE_SIZE, PAGE_SIZE, PAGE_SIZE, MREMAP_FIXED | MREMAP_MAYMOVE, temp);
mremap(m, PAGE_SIZE, PAGE_SIZE, MREMAP_FIXED | MREMAP_MAYMOVE, m+PAGE_SIZE);
mremap(temp, PAGE_SIZE, PAGE_SIZE, MREMAP_FIXED | MREMAP_MAYMOVE, m);
printf("after %c %c\n", m[0], m[PAGE_SIZE]);
return 0;
}
這正是我所需要的。感謝Adam! – feradz 2015-08-11 15:18:38
這工作正好。 Linux mremap上的 可以移動由mmap分配的頁面。 – Adam 2010-04-21 04:41:18