Can I move a memory page by changing the page table?

Is it possible (on any reasonable OS, preferably Linux) to exchange the contents of two pages of memory, only changing the page table and actually not moving any data?

Motivation is a dense matrix transposition. If the data was locked by page size, you could transpose the data inside the page (fits into the cache), and then exchange the pages to move the blocks to their last place. A large matrix would have many pages, so we hope that resetting the TLB will not cause problems.

+3
source share
3 answers

I think memory mapped files can do the trick, but I believe I never tried this myself. Use mmap with MAP_ANONYMOUS to match a pure virtual address (without physical file support). Then you can reassign your “file” to various areas of VA, resulting in a zero copy semantics. On Windows, you use MapViewOfFile with the file association descriptor created using CreateMapOfFile (INVALID_HANDLE_VALUE, ...), but note that on NT you cannot (i.e. the newly mapped VA address is the output of the function call), and on Linux, the desired address is taken as a hint.

If this does not work, you will probably need to create a memory module in the kernel, which is impossible for any practical project.

0
#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;
}
+1

In theory, of course. In practice, I think you can use mmap () to move V-style shared memory blocks this way.

-1
source

Source: https://habr.com/ru/post/1742025/


All Articles