# Experiment: Check NUMA node from a pointer contributed by `JulianATA(Julian Fang)` ## Environment ```bash $uname -a Linux 4.15.0-62-generic x86_64 GNU/Linux ``` ## numaif.h/move_pages ```c #include <numaif.h> long move_pages(int pid, unsigned long count, void **pages, const int *nodes, int *status, int flags); ``` :::warning Link with -lnuma. ::: :::info nodes is an array of integers that specify the desired location for each page. Each element in the array is a node number. `nodes can also be NULL`, in which case move_pages() does not move any pages `but instead will return the node where each page currently resides`, in the status array. Obtaining the status of each page may be necessary to determine pages that need to be moved. ::: ## Implementation ### numa get node * The goal here is to return the resident node of pointer p by using `move_pages()`. ```c int get_node(void* p){ int numa_node[1] = {-1}; void* page = (void*)((size_t)p & ~((size_t)getpagesize()-1)); int err = move_pages(getpid(), 1, &page , NULL, numa_node, 0); if(err == -1){ printf("move page failed.\n"); return -1; } return numa_node[0]; } ``` ### Experment(`set_mempolicy()`) ```c #include <stdio.h> #include <stdlib.h> #include <numaif.h> //set_mempolicy #include "numagetnode.h" #define MAX_NODES 4 #define TESTING_TIME 50 int main(int argc, char** argv) { // get size and node informations size_t size = atoi(argv[1]); int node = atoi(argv[2]); // set memory policy by node unsigned long mask = (1UL << node); long err = set_mempolicy(MPOL_BIND, &mask, MAX_NODES); if(err == -1){ printf("Set mem policy failed.\n"); return -1; } // Allocation test for(int i = 0; i< TESTING_TIME; i++){ void* p = malloc(size); if(p == NULL){ printf("Allocate failed\n"); return -1; } printf("allocate an object with size:%ld on node:%d\n", size, node); //get resident node by pointer printf("memory %p is on node:%d\n", p, get_node(p)); } return 0; } ``` * Test for 50 times(default) * Use `set_mempolicy()` as an instance. * Using `malloc()` ```bash $./get_node 128 2 allocate an object with size:128 on node:2 memory 0x55e131263130 is on node:2 allocate an object with size:128 on node:2 memory 0x55e1312631c0 is on node:2 allocate an object with size:128 on node:2 memory 0x55e131263250 is on node:2 allocate an object with size:128 on node:2 memory 0x55e1312632e0 is on node:2 allocate an object with size:128 on node:2 memory 0x55e131263370 is on node:2 allocate an object with size:128 on node:2 memory 0x55e131263400 is on node:2 allocate an object with size:128 on node:2 memory 0x55e131263490 is on node:2 allocate an object with size:128 on node:2 . . . ``` --- ```c #include <stdio.h> #include <stdlib.h> #include <numaif.h> //set_mempolicy #include <sys/mman.h> //mmap #include <unistd.h> #include <string.h> #include "numagetnode.h" #define MAX_NODES 4 #define TESTING_TIME 5 int main(int argc, char** argv) { // get node informations int size = atoi(argv[1]); int node = atoi(argv[2]); // set memory policy by node unsigned long mask = (1UL << node); long err = set_mempolicy(MPOL_BIND, &mask, MAX_NODES); if(err == -1){ printf("Set mem policy failed.\n"); return -1; } // Allocation test for(int i = 0; i< TESTING_TIME; i++){ char* p = (char*)mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); if(p == NULL){ printf("Allocate failed\n"); return -1; } printf("allocate an object with size:%d on node:%d\n", size, node); //need to be read|write before testing memset(p, '\0', sizeof(p)); //get resident node by pointer printf("memory %p is on node:%d\n", p, get_node(p)); } ``` * Test for 5 times(default) * Use `set_mempolicy()` as an instance. * Using `mmap` ```bash $./main 1024 0 allocate an object with size:1024 on node:0 memory 0x7f25445f0000 is on node:0 allocate an object with size:1024 on node:0 memory 0x7f25445ef000 is on node:0 allocate an object with size:1024 on node:0 memory 0x7f25445ee000 is on node:0 allocate an object with size:1024 on node:0 memory 0x7f25445ed000 is on node:0 allocate an object with size:1024 on node:0 memory 0x7f25445ec000 is on node:0 ``` ###### tags: `NUMA`