Back to index

numactl  2.0.8~rc4
migspeed.c
Go to the documentation of this file.
00001 /*
00002  * Migration test program
00003  *
00004  * (C) 2007 Silicon Graphics, Inc. Christoph Lameter <clameter@sgi.com>
00005  *
00006  */
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include "numa.h"
00010 #include "numaif.h"
00011 #include <time.h>
00012 #include <errno.h>
00013 #include <malloc.h>
00014 #include <unistd.h>
00015 #include "util.h"
00016 
00017 char *memory;
00018 
00019 unsigned long pages = 1000;
00020 
00021 unsigned long pagesize;
00022 
00023 const char *optstr = "hvp:";
00024 
00025 char *cmd;
00026 
00027 int verbose;
00028 struct timespec start,end;
00029 
00030 void usage(void)
00031 {
00032        printf("usage %s [-p pages] [-h] [-v] from-nodes to-nodes\n", cmd);
00033        printf("      from and to nodes may specified in form N or N-N\n");
00034        printf("      -p pages  number of pages to try (defaults to %ld)\n",
00035                      pages);
00036        printf("      -v        verbose\n");
00037        printf("      -h        usage\n");
00038        exit(1);
00039 }
00040 
00041 void displaymap(void)
00042 {
00043        FILE *f = fopen("/proc/self/numa_maps","r");
00044 
00045        if (!f) {
00046               printf("/proc/self/numa_maps not accessible.\n");
00047               exit(1);
00048        }
00049 
00050        while (!feof(f))
00051        {
00052               char buffer[2000];
00053 
00054               if (!fgets(buffer, sizeof(buffer), f))
00055                      break;
00056               if (!strstr(buffer, "bind"))
00057                      continue ;
00058               printf("%s", buffer);
00059 
00060        }
00061        fclose(f);
00062 }
00063 
00064 int main(int argc, char *argv[])
00065 {
00066        char *p;
00067        int option;
00068        int error = 0;
00069        struct timespec result;
00070        unsigned long bytes;
00071        double duration, mbytes;
00072        struct bitmask *from;
00073        struct bitmask *to;
00074 
00075        pagesize = getpagesize();
00076 
00077        /* Command line processing */
00078        opterr = 1;
00079        cmd = argv[0];
00080 
00081        while ((option = getopt(argc, argv, optstr)) != EOF)
00082        switch (option) {
00083        case 'h' :
00084        case '?' :
00085               error = 1;
00086               break;
00087        case 'v' :
00088               verbose++;
00089               break;
00090        case 'p' :
00091               pages = strtoul(optarg, &p, 0);
00092               if (p == optarg || *p)
00093                      usage();
00094               break;
00095        }
00096 
00097        if (!argv[optind])
00098               usage();
00099 
00100        if (verbose > 1)
00101               printf("numa_max_node = %d\n", numa_max_node());
00102 
00103        numa_exit_on_error = 1;
00104 
00105        from = numa_parse_nodestring(argv[optind]);
00106        if (!from) {
00107                 printf ("<%s> is invalid\n", argv[optind]);
00108               exit(1);
00109        }
00110        if (errno) {
00111               perror("from mask");
00112               exit(1);
00113        }
00114 
00115        if (verbose)
00116               printmask("From", from);
00117 
00118        if (!argv[optind+1])
00119               usage();
00120 
00121        to = numa_parse_nodestring(argv[optind+1]);
00122        if (!to) {
00123                 printf ("<%s> is invalid\n", argv[optind+1]);
00124               exit(1);
00125        }
00126        if (errno) {
00127               perror("to mask");
00128               exit(1);
00129        }
00130 
00131        if (verbose)
00132               printmask("To", to);
00133 
00134        bytes = pages * pagesize;
00135 
00136        if (verbose)
00137               printf("Allocating %lu pages of %lu bytes of memory\n",
00138                             pages, pagesize);
00139 
00140        memory = memalign(pagesize, bytes);
00141 
00142        if (!memory) {
00143               printf("Out of Memory\n");
00144               exit(2);
00145        }
00146 
00147        if (mbind(memory, bytes, MPOL_BIND, from->maskp, from->size, 0) < 0)
00148               numa_error("mbind");
00149 
00150        if (verbose)
00151               printf("Dirtying memory....\n");
00152 
00153        for (p = memory; p <= memory + bytes; p += pagesize)
00154               *p = 1;
00155 
00156        if (verbose)
00157               printf("Starting test\n");
00158 
00159        displaymap();
00160        clock_gettime(CLOCK_REALTIME, &start);
00161 
00162        if (mbind(memory, bytes, MPOL_BIND, to->maskp, to->size, MPOL_MF_MOVE) <0)
00163               numa_error("memory move");
00164 
00165        clock_gettime(CLOCK_REALTIME, &end);
00166        displaymap();
00167 
00168        result.tv_sec = end.tv_sec - start.tv_sec;
00169        result.tv_nsec = end.tv_nsec - start.tv_nsec;
00170 
00171        if (result.tv_nsec < 0) {
00172               result.tv_sec--;
00173               result.tv_nsec += 1000000000;
00174        }
00175 
00176        if (result.tv_nsec >= 1000000000) {
00177               result.tv_sec++;
00178               result.tv_nsec -= 1000000000;
00179        }
00180 
00181        duration = result.tv_sec + result.tv_nsec / 1000000000.0;
00182        mbytes = bytes / (1024*1024.0);
00183 
00184        printf("%1.1f Mbyte migrated in %1.2f secs. %3.1f Mbytes/second\n",
00185                      mbytes,
00186                      duration,
00187                      mbytes / duration);
00188        return 0;
00189 }
00190