diff options
author | Huang Ying <ying.huang@intel.com> | 2016-12-22 16:37:15 +0800 |
---|---|---|
committer | Fengguang Wu <fengguang.wu@intel.com> | 2016-12-28 22:58:38 +0800 |
commit | e16597d368253095d16e331ab07baf8b443d2254 (patch) | |
tree | 489a53bcba36c0ee5ca4f7dbb99c53a03cd70a62 | |
parent | 4e789c9ce3bf9d6d4c70f52bfe13c60110190bdd (diff) | |
download | vm-scalability-e16597d368253095d16e331ab07baf8b443d2254.tar.gz |
Support binding tasks to CPU
Signed-off-by: "Huang, Ying" <ying.huang@intel.com>
Signed-off-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
-rwxr-xr-x | hw_vars | 1 | ||||
-rw-r--r-- | usemem.c | 68 |
2 files changed, 63 insertions, 6 deletions
@@ -7,6 +7,7 @@ else fi [ -n "$SYNC_RW" ] && USEMEM="$USEMEM -y" +[ -n "$BIND_CPU" ] && USEMEM="$USEMEM -b $BIND_CPU" TMPFS_MNT=/tmp/vm-scalability-tmp SHM_FILE=$TMPFS_MNT/sparse-${0#*case-} @@ -27,6 +27,7 @@ #include <sys/shm.h> #include <sys/syscall.h> #include <poll.h> +#include <sched.h> #include "usemem_mincore.h" #include "usemem_hugepages.h" @@ -75,9 +76,11 @@ int opt_mincore = 0; int opt_mincore_hugepages = 0; int opt_write_signal_read = 0; int opt_sync_rw = 0; +int opt_bind_interval = 0; int sem_id = -1; int nr_task; int nr_thread; +int nr_cpu; int quiet = 0; int msync_mode; char *filename = "/dev/zero"; @@ -95,6 +98,7 @@ void usage(int ok) "Usage: %s [options] size[k|m|g|t]\n" " -n|--nproc N do job in N processes\n" " -t|--thread M do job in M threads\n" + " -b|--bind N bind tasks with CPU number internal as N\n" " -a|--malloc obtain memory from malloc()\n" " -f|--file FILE mmap FILE, default /dev/zero\n" " -F|--prefault prefault mmap with MAP_POPULATE\n" @@ -140,6 +144,7 @@ static const struct option opts[] = { { "msync-async" , 0, NULL, 'A' }, { "nproc" , 1, NULL, 'n' }, { "thread" , 1, NULL, 't' }, + { "bind" , 1, NULL, 'b' }, { "prealloc" , 0, NULL, 'P' }, { "prefault" , 0, NULL, 'F' }, { "repeat" , 1, NULL, 'r' }, @@ -660,15 +665,36 @@ long do_units(void) typedef void * (*start_routine)(void *); -int do_task(void) +static inline int bind_cpu(int task_nr) +{ + return task_nr * opt_bind_interval % nr_cpu; +} + +int do_task(int task_nr) { pthread_t threads[nr_thread]; long thread_ret; int ret; int i; + cpu_set_t *mask; + size_t size; + + size = CPU_ALLOC_SIZE(nr_cpu); + mask = CPU_ALLOC(nr_cpu); + if (mask == NULL) { + perror("CPU_ALLOC"); + exit(1); + } - if (!nr_thread) + if (!nr_thread) { + if (opt_bind_interval) { + CPU_ZERO_S(size, mask); + CPU_SET_S(bind_cpu(task_nr), size, mask); + sched_setaffinity(getpid(), size, mask); + CPU_FREE(mask); + } return do_units(); + } for (i = 0; i < nr_thread; i++) { ret = pthread_create(&threads[i], NULL, (start_routine)do_units, NULL); @@ -676,7 +702,19 @@ int do_task(void) perror("pthread_create"); exit(1); } + if (opt_bind_interval) { + CPU_ZERO_S(size, mask); + CPU_SET_S(bind_cpu(task_nr * nr_thread + i), size, mask); + ret = pthread_setaffinity_np(threads[i], size, mask); + if (ret) { + perror("pthread_setaffinity_np"); + exit(1); + } + } } + + CPU_FREE(mask); + for (i = 0; i < nr_thread; i++) { ret = pthread_join(threads[i], (void *)&thread_ret); if (ret) { @@ -696,9 +734,11 @@ int do_tasks(void) char dummy; for (i = 0; i < nr_task; i++) { - if ((child_pid = fork()) == 0) { - return do_task(); - } + if ((child_pid = fork()) == 0) + return do_task(i); + else if (child_pid < 0) + fprintf(stderr, "failed to fork: %s\n", + strerror(errno)); } for (i = 0; i < nr_task * nr_thread; i++) @@ -743,7 +783,7 @@ int main(int argc, char *argv[]) pagesize = getpagesize(); while ((c = getopt_long(argc, argv, - "aAf:FPp:gqowRMm:n:t:ds:T:Sr:u:j:EHDNLWyh", opts, NULL)) != -1) + "aAf:FPp:gqowRMm:n:t:b:ds:T:Sr:u:j:EHDNLWyh", opts, NULL)) != -1) { switch (c) { case 'a': @@ -778,6 +818,9 @@ int main(int argc, char *argv[]) case 't': nr_thread = strtol(optarg, NULL, 10); break; + case 'b': + opt_bind_interval = strtol(optarg, NULL, 10); + break; case 'P': prealloc++; break; @@ -856,6 +899,19 @@ int main(int argc, char *argv[]) exit(1); } + nr_cpu = sysconf(_SC_NPROCESSORS_ONLN); + if (nr_cpu < 0) { + fprintf(stderr, "%s: failed to get online CPU number: %s\n", + ourname, strerror(errno)); + exit(1); + } + + if (opt_bind_interval >= nr_cpu) { + fprintf(stderr, "%s: invalid binding interval %d for %d CPUs\n", + ourname, opt_bind_interval, nr_cpu); + exit(1); + } + if (step < sizeof(long)) step = sizeof(long); |