Может ли страница памяти перемещаться, изменяя таблицу страницы?
Вопрос
Возможно ли (на любую разумную ОС, предпочтительно Linux) поменять содержимое двух страниц памяти, только изменяя таблицу страницы, а не на самом деле перемещать какие-либо данные?
Мотивация - это плотная матрица. Если данные были заблокированы по размеру страницы, можно было бы возможно транспонировать данные на странице (вписываются в кэш), а затем поменяйте страницы, чтобы переместить блоки в их конечное место. Большая матрица будет иметь многочисленные многочисленные страницы, поэтому, надеюсь, промывая TLB не приведет к неприятностям.
Решение
Я думаю, что памяти отображаются файлы могут сделать трюк, но я считаю, что я никогда не пробовал это сам. Использовать MMAP С Map_Anonymous на карту через чистый виртуальный адрес (без поддержки физического файла). Затем вы можете перенаправить свой «файл» в различные области получения VA в эффекте семантики нулевой копии. В Windows вы бы использовали Mapviewoffile. С помощью ручки отображения файлов, созданные с помощью CreateMapOffile (Invalid_Handle_Value, ...), но примечание, чем на NT, вы не можете контролировать цель вашего перенаправления (то есть. Новый сопоставленный адрес VA является выход вызова функции), а на Linux желаемый адрес принимается как намекать.
Если это не работает, то вам, вероятно, нужно создать модуль менеджера памяти в ядре, который не выполнен для любого практического проекта.
Другие советы
#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;
}
Теоретически, конечно. На практике я думать Вы можете использовать MMAP (), чтобы переместить блокировку общей памяти системы V-стиля.