diff --git a/ggml/src/ggml-cpu/repack.cpp b/ggml/src/ggml-cpu/repack.cpp index 4471c9ab1daf..6135504bf5d3 100644 --- a/ggml/src/ggml-cpu/repack.cpp +++ b/ggml/src/ggml-cpu/repack.cpp @@ -18,6 +18,35 @@ #include "repack.h" +#if defined(__linux__) +#include +#include +#include + +// move the pages of [start, end) to the NUMA node of the calling thread (best effort) +static void ggml_repack_move_pages_to_local_node(const void * start, const void * end) { + unsigned cpu = 0; + unsigned node = 0; + if (syscall(SYS_getcpu, &cpu, &node, NULL) != 0) { + return; + } + const uintptr_t page = (uintptr_t) sysconf(_SC_PAGESIZE); + uintptr_t addr = (uintptr_t) start & ~(page - 1); + const uintptr_t stop = (uintptr_t) end; + void * pages[256]; + int nodes[256]; + int status[256]; + while (addr < stop) { + int n = 0; + for (; n < 256 && addr < stop; n++, addr += page) { + pages[n] = (void *) addr; + nodes[n] = (int) node; + } + syscall(SYS_move_pages, 0, (unsigned long) n, pages, nodes, status, 2 /* MPOL_MF_MOVE */); + } +} +#endif + #if defined(__GNUC__) #pragma GCC diagnostic ignored "-Woverlength-strings" #endif @@ -5054,6 +5083,24 @@ template placed; + if (placed.insert((uintptr_t) src0->data ^ ((uintptr_t) nth << 48)).second) { + int64_t r0 = dr0 * ith; + int64_t r1 = MIN(r0 + dr0, nr0); + r0 = (r0 % NB_COLS) ? r0 + NB_COLS - (r0 % NB_COLS) : r0; + r1 = (r1 % NB_COLS) ? r1 + NB_COLS - (r1 % NB_COLS) : r1; + r1 = MIN(r1, ne01); + if (r0 < r1) { + ggml_repack_move_pages_to_local_node((const char *) src0->data + r0 * nb01, (const char *) src0->data + r1 * nb01); + } + } + } +#endif + while (current_chunk < nchunk0 * nchunk1) { const int64_t ith0 = current_chunk % nchunk0; const int64_t ith1 = current_chunk / nchunk0;