| [70c4392] | 1 | /*
|
|---|
| 2 | NUMA helper functions
|
|---|
| 3 | (C) Romain Dolbeau : CAPS
|
|---|
| 4 | */
|
|---|
| 5 | /*
|
|---|
| 6 |
|
|---|
| 7 | This software is governed by the CeCILL license under French law and
|
|---|
| 8 | abiding by the rules of distribution of free software. You can use,
|
|---|
| 9 | modify and/ or redistribute the software under the terms of the CeCILL
|
|---|
| 10 | license as circulated by CEA, CNRS and INRIA at the following URL
|
|---|
| 11 | "http://www.cecill.info".
|
|---|
| 12 |
|
|---|
| 13 | As a counterpart to the access to the source code and rights to copy,
|
|---|
| 14 | modify and redistribute granted by the license, users are provided only
|
|---|
| 15 | with a limited warranty and the software's author, the holder of the
|
|---|
| 16 | economic rights, and the successive licensors have only limited
|
|---|
| 17 | liability.
|
|---|
| 18 |
|
|---|
| 19 | In this respect, the user's attention is drawn to the risks associated
|
|---|
| 20 | with loading, using, modifying and/or developing or reproducing the
|
|---|
| 21 | software by the user in light of its specific status of free software,
|
|---|
| 22 | that may mean that it is complicated to manipulate, and that also
|
|---|
| 23 | therefore means that it is reserved for developers and experienced
|
|---|
| 24 | professionals having in-depth computer knowledge. Users are therefore
|
|---|
| 25 | encouraged to load and test the software's suitability as regards their
|
|---|
| 26 | requirements in conditions enabling the security of their systems and/or
|
|---|
| 27 | data to be ensured and, more generally, to use and operate it in the
|
|---|
| 28 | same conditions as regards security.
|
|---|
| 29 |
|
|---|
| 30 | The fact that you are presently reading this means that you have had
|
|---|
| 31 | knowledge of the CeCILL license and that you accept its terms.
|
|---|
| 32 |
|
|---|
| 33 | */
|
|---|
| 34 |
|
|---|
| 35 | #include "hydro_numa.h"
|
|---|
| 36 | #include <stdlib.h>
|
|---|
| 37 | #include <stdio.h>
|
|---|
| 38 | #include <numaif.h>
|
|---|
| 39 | #include <errno.h>
|
|---|
| 40 |
|
|---|
| 41 | #define ASSUMED_PAGE_SIZE 4096
|
|---|
| 42 | void force_move_pages(const void* data_, const size_t n, const size_t selem,
|
|---|
| 43 | const enum numa_distrib_type distrib, const size_t distrib_parameter) {
|
|---|
| 44 | const char* data = (const char*)data_;
|
|---|
| 45 | const size_t elem_per_page = ASSUMED_PAGE_SIZE/selem;
|
|---|
| 46 | const size_t np = n / elem_per_page;
|
|---|
| 47 | int status[np];
|
|---|
| 48 | int nodes[np];
|
|---|
| 49 | const char* pages[np];
|
|---|
| 50 | size_t i;
|
|---|
| 51 | long res;
|
|---|
| 52 |
|
|---|
| 53 | #ifndef __MIC__
|
|---|
| 54 | const int nmn = numa_num_configured_nodes();
|
|---|
| 55 |
|
|---|
| 56 | // fprintf(stderr, "%s:%d elem_per_page = %zd, nmn = %d ; np = %zd\n", __PRETTY_FUNCTION__, __LINE__, elem_per_page, nmn, np);
|
|---|
| 57 |
|
|---|
| 58 | for (i = 0 ; i < np ; i++) {
|
|---|
| 59 | pages[i] = data + i * ASSUMED_PAGE_SIZE;
|
|---|
| 60 | switch (distrib) {
|
|---|
| 61 | case HYDRO_NUMA_NONE:
|
|---|
| 62 | nodes[i] = -1;
|
|---|
| 63 | break;
|
|---|
| 64 | case HYDRO_NUMA_INTERLEAVED:
|
|---|
| 65 | nodes[i] = i % nmn;
|
|---|
| 66 | break;
|
|---|
| 67 | case HYDRO_NUMA_ONE_BLOCK_PER_NODE: {
|
|---|
| 68 | const size_t ppernode = np / nmn;
|
|---|
| 69 | size_t nnode = i / ppernode;
|
|---|
| 70 | if (nnode > (nmn-1))
|
|---|
| 71 | nnode = nmn - 1;
|
|---|
| 72 | nodes[i] = nnode;
|
|---|
| 73 | } break;
|
|---|
| 74 | case HYDRO_NUMA_SIZED_BLOCK_RR: {
|
|---|
| 75 | const size_t numb = i / (distrib_parameter/elem_per_page);
|
|---|
| 76 | size_t nnode = numb % nmn;
|
|---|
| 77 | nodes[i] = nnode;
|
|---|
| 78 | } break;
|
|---|
| 79 | }
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | if (HYDRO_NUMA_NONE != distrib) {
|
|---|
| 83 | res = move_pages(0, np, (void**)pages, nodes, status, MPOL_MF_MOVE);
|
|---|
| 84 | } else {
|
|---|
| 85 | res = move_pages(0, np, (void**)pages, NULL , status, MPOL_MF_MOVE);
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | if (res != 0) {
|
|---|
| 89 | fprintf(stderr, "%s:%d: move_pages -> errno = %d\n", __PRETTY_FUNCTION__, __LINE__, errno);
|
|---|
| 90 | } else {
|
|---|
| 91 | int last_node = status[0];
|
|---|
| 92 | const char* last;
|
|---|
| 93 | const char* cur = data;
|
|---|
| 94 | // fprintf(stderr, "%s:%d: move_pages for %p of %zd elements (%zd bytes)\n", __PRETTY_FUNCTION__, __LINE__, data, n, n * selem);
|
|---|
| 95 | // fprintf(stderr, "\t%d: %p ... ", last_node, cur );
|
|---|
| 96 | last = cur;
|
|---|
| 97 | for (i = 1 ; i < np ; i++) {
|
|---|
| 98 | if (status[i] != last_node) {
|
|---|
| 99 | cur += ASSUMED_PAGE_SIZE;
|
|---|
| 100 | // fprintf(stderr, "%p (%llu)\n", cur, (unsigned long long)cur - (unsigned long long)last);
|
|---|
| 101 | last_node = status[i];
|
|---|
| 102 | // fprintf(stderr, "\t%d: %p ... ", last_node, cur);
|
|---|
| 103 | last = cur;
|
|---|
| 104 | } else {
|
|---|
| 105 | cur += ASSUMED_PAGE_SIZE;
|
|---|
| 106 | }
|
|---|
| 107 | }
|
|---|
| 108 | // fprintf(stderr, "%p (%llu)\n", cur, (unsigned long long)cur - (unsigned long long)last);
|
|---|
| 109 | }
|
|---|
| 110 | #endif
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|