Skip to content

Commit

Permalink
This patch adds the migspeed test program.
Browse files Browse the repository at this point in the history
It tests the speed of migrating pages from one node to another.

Diffed against numactl-1.0.2

Signed-off-by: Christoph Lameter <clameter@sgi.com>
  • Loading branch information
Christoph Lameter authored and filbranden committed Jul 23, 2014
1 parent ad77dd3 commit d004857
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 7 deletions.
18 changes: 11 additions & 7 deletions Makefile
Expand Up @@ -22,8 +22,7 @@ CLEANFILES := numactl.o libnuma.o numactl numademo numademo.o distance.o \
test/pagesize test/tshared test/mynode.o test/tshared.o mt.o \
test/mynode test/ftok test/prefered test/randmap \
.depend .depend.X test/nodemap test/distance test/tbitmap \
test/after test/before threadtest migratepages

test/after test/before threadtest migratepages migspeed
SOURCES := bitops.c libnuma.c distance.c memhog.c numactl.c numademo.c \
numamon.c shm.c stream_lib.c stream_main.c syscall.c util.c mt.c \
test/*.c
Expand All @@ -32,14 +31,17 @@ prefix := /usr
libdir := ${prefix}/$(shell ./getlibdir)
docdir := ${prefix}/share/doc

all: numactl migratepages libnuma.so numademo numamon memhog test/tshared stream \
test/mynode test/pagesize test/ftok test/prefered test/randmap \
test/nodemap test/distance test/tbitmap
all: numactl migratepages migspeed libnuma.so numademo numamon memhog \
test/tshared stream test/mynode test/pagesize test/ftok test/prefered \
test/randmap test/nodemap test/distance test/tbitmap

numactl: numactl.o util.o shm.o bitops.o libnuma.so

migratepages: migratepages.c util.o bitops.o libnuma.so

migspeed: migspeed.o util.o libnuma.so
${CC} migspeed.c -o migspeed util.o libnuma.so -lrt

util.o: util.c

memhog: util.o memhog.o libnuma.so
Expand Down Expand Up @@ -91,6 +93,7 @@ test/nodemap: test/nodemap.c libnuma.so

test/distance: test/distance.c libnuma.so


test/tbitmap: test/tbitmap.c libnuma.so

.PHONY: install all clean html depend
Expand All @@ -104,12 +107,13 @@ run_on_node_mask set_bind_policy set_interleave_mask set_localalloc \
set_membind set_preferred set_strict setlocal_memory tonode_memory \
tonodemask_memory distance

MANPAGES := numa.3 numactl.8 numastat.8 migratepages.8
MANPAGES := numa.3 numactl.8 numastat.8 migratepages.8 migspeed.8

install: numactl migratepages numademo.c numamon memhog libnuma.so.1 numa.h numaif.h numastat ${MANPAGES}
install: numactl migratepages migspeed numademo.c numamon memhog libnuma.so.1 numa.h numaif.h numastat ${MANPAGES}
mkdir -p ${prefix}/bin
cp numactl ${prefix}/bin
cp migratepages ${prefix}/bin
cp migspeed ${prefix}/bin
cp numademo ${prefix}/bin
cp memhog ${prefix}/bin
mkdir -p ${prefix}/share/man/man2 ${prefix}/share/man/man8 ${prefix}/share/man/man3
Expand Down
31 changes: 31 additions & 0 deletions migspeed.8
@@ -0,0 +1,31 @@
.\" t
.\" Copyright 2005-2007 Christoph Lameter, Silicon Graphics, Inc.
.\"
.\" based on Andi Kleen's numactl manpage
.\"
.TH MIGSPEED 8 "April 2005" "SGI" "Linux Administrator's Manual"
.SH NAME
migspeed \- Test the speed of page migration
.SH SYNOPSIS
.B migspeed
-p pages from-nodes to-nodes
.SH DESCRIPTION
.B migspeed
attempts to move a sample of pages from the indicated node to the target node
and measures the time it takes to perform the move.

.B -p pages

The default sample is 1000 pages. Override that with another number.

.SH NOTES
Requires an NUMA policy aware kernel with support for page migration
(Linux 2.6.16 and later).

.SH COPYRIGHT
Copyright 2007 Christoph Lameter, Silicon Graphics, Inc.
migratepages is under the GNU General Public License, v.2

.SH SEE ALSO
.I numactl(8)

185 changes: 185 additions & 0 deletions migspeed.c
@@ -0,0 +1,185 @@
/*
* Migration test program
*
* (C) 2007 Silicon Graphics, Inc. Christoph Lameter <clameter@sgi.com>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "numa.h"
#include <numaif.h>
#include <time.h>
#include <errno.h>
#include <malloc.h>
#include <unistd.h>
#include "util.h"

char *memory;

unsigned long pages = 1000;

unsigned long pagesize;

const char *optstr = "hvp:";

char *cmd;

int verbose;
struct timespec start,end;

void usage(void)
{
printf("usage %s [-p pages] [-h] [-v] from-nodes to-nodes\n", cmd);
printf(" from and to nodes may specified in form N or N-N\n");
printf(" -p pages number of pages to try (defaults to %ld)\n",
pages);
printf(" -v verbose\n");
printf(" -h usage\n");
exit(1);
}

int numa_exit_on_error = 1;

void displaymap(void)
{
FILE *f = fopen("/proc/self/numa_maps","r");

if (!f) {
printf("/proc/self/numa_maps not accessible.\n");
exit(1);
}

while (!feof(f))
{
char buffer[2000];

if (!fgets(buffer, sizeof(buffer), f))
break;
if (!strstr(buffer, "bind"))
continue ;
printf(buffer);

}
fclose(f);
}

int main(int argc, char *argv[])
{
char *p;
int option;
int error = 0;
struct timespec result;
unsigned long bytes;
double duration, mbytes;
nodemask_t from;
nodemask_t to;

pagesize = getpagesize();

/* Command line processing */
opterr = 1;
cmd = argv[0];

while ((option = getopt(argc, argv, optstr)) != EOF)
switch (option) {
case 'h' :
case '?' :
error = 1;
break;
case 'v' :
verbose++;
break;
case 'p' :
pages = strtoul(optarg, &p, 0);
if (p == optarg || *p)
usage();
break;
}

if (!argv[optind])
usage();

if (verbose > 1)
printf("numa_max_node = %d NUMA_NUM_NODES=%d\n",
numa_max_node(), NUMA_NUM_NODES);

from = nodemask(argv[optind]);
if (errno) {
perror("from mask");
exit(1);
}

if (verbose)
printmask("From", &from);

if (!argv[optind+1])
usage();

to = nodemask(argv[optind+1]);
if (errno) {
perror("to mask");
exit(1);
}

if (verbose)
printmask("To", &to);

bytes = pages * pagesize;

if (verbose)
printf("Allocating %lu pages of %lu bytes of memory\n",
pages, pagesize);

memory = memalign(pagesize, bytes);

if (!memory) {
printf("Out of Memory\n");
exit(2);
}

if (mbind(memory, bytes, MPOL_BIND, (unsigned long *)&from,
NUMA_NUM_NODES+1, 0) < 0)
numa_error("mbind");

if (verbose)
printf("Dirtying memory....\n");

for (p = memory; p <= memory + bytes; p += pagesize)
*p = 1;

if (verbose)
printf("Starting test\n");

displaymap();
clock_gettime(CLOCK_REALTIME, &start);

if (mbind(memory, bytes, MPOL_BIND, (unsigned long *)&to,
NUMA_NUM_NODES+1, MPOL_MF_MOVE)<0)
numa_error("memory move");

clock_gettime(CLOCK_REALTIME, &end);
displaymap();

result.tv_sec = end.tv_sec - start.tv_sec;
result.tv_nsec = end.tv_nsec - start.tv_nsec;

if (result.tv_nsec < 0) {
result.tv_sec--;
result.tv_nsec += 1000000000;
}

if (result.tv_nsec >= 1000000000) {
result.tv_sec++;
result.tv_nsec -= 1000000000;
}

duration = result.tv_sec + result.tv_nsec / 1000000000.0;
mbytes = bytes / (1024*1024.0);

printf("%1.1f Mbyte migrated in %1.2f secs. %3.1f Mbytes/second\n",
mbytes,
duration,
mbytes / duration);
return 0;
}

0 comments on commit d004857

Please sign in to comment.