From: Martin Quinson Date: Sat, 5 Mar 2016 22:21:05 +0000 (+0100) Subject: try to bind worker threads to cores when possible X-Git-Tag: v3_13~537 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/fbf3527063143094ed40d1a4a3bc595c29b81145?hp=f1beb44a3ba0bbbcac9ed2cb221b48da9273d0c7 try to bind worker threads to cores when possible --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 152eb9607f..dfd7569c8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,12 +270,12 @@ CHECK_LIBRARY_EXISTS(pthread sem_init "" HAVE_SEM_INIT_LIB) CHECK_LIBRARY_EXISTS(pthread sem_open "" HAVE_SEM_OPEN_LIB) CHECK_LIBRARY_EXISTS(pthread sem_timedwait "" HAVE_SEM_TIMEDWAIT_LIB) CHECK_LIBRARY_EXISTS(pthread pthread_mutex_timedlock "" HAVE_MUTEX_TIMEDLOCK_LIB) - +CHECK_LIBRARY_EXISTS(pthread pthread_setaffinity_np "" HAVE_PTHREAD_SETAFFINITY) if(CMAKE_SYSTEM_NAME MATCHES "Darwin") set(CMAKE_REQUIRED_DEFINITIONS "-D_XOPEN_SOURCE=700 -D_DARWIN_C_SOURCE") elseif(MINGW) - # Use the GNU version of unusual modifiers like PRIx64 + # Use the GNU version of unusual modifiers like PRIx64 add_definitions(-D__USE_MINGW_ANSI_STDIO=1) set(CMAKE_REQUIRED_DEFINITIONS "-D__USE_MINGW_ANSI_STDIO=1") else() diff --git a/include/xbt/xbt_os_thread.h b/include/xbt/xbt_os_thread.h index 3891cc8adc..3d9542941d 100644 --- a/include/xbt/xbt_os_thread.h +++ b/include/xbt/xbt_os_thread.h @@ -41,13 +41,13 @@ XBT_PUBLIC(int) xbt_os_thread_atfork(void (*prepare)(void), void (*parent)(void) XBT_PUBLIC(int) xbt_os_get_numcores(void); -XBT_PUBLIC(xbt_os_thread_t) xbt_os_thread_create(const char *name, pvoid_f_pvoid_t start_routine, void *param, - void *data); +XBT_PUBLIC(xbt_os_thread_t) xbt_os_thread_create(const char *name, pvoid_f_pvoid_t start_routine, void *param, void *data); -//#define CORE_BINDING //Uncomment this to enable binding of threads to physical cores. Only Linux. -#ifdef CORE_BINDING -XBT_PUBLIC(int) xbt_os_thread_bind(xbt_os_thread_t thread, int cpu); -#endif +/** Bind the thread to the given core, if possible. + * + * If pthread_setaffinity_np is not usable on that (non-gnu) platform, this function does nothing. + */ +XBT_PUBLIC(int) xbt_os_thread_bind(xbt_os_thread_t thread, int core); XBT_PUBLIC(void) xbt_os_thread_exit(int *retcode); XBT_PUBLIC(void) xbt_os_thread_detach(xbt_os_thread_t thread); diff --git a/src/xbt/parmap.cpp b/src/xbt/parmap.cpp index d3edb7b061..88431cc0d2 100644 --- a/src/xbt/parmap.cpp +++ b/src/xbt/parmap.cpp @@ -120,8 +120,6 @@ typedef s_xbt_parmap_thread_data_t *xbt_parmap_thread_data_t; */ xbt_parmap_t xbt_parmap_new(unsigned int num_workers, e_xbt_parmap_mode_t mode) { - unsigned int i; - XBT_DEBUG("Create new parmap (%u workers)", num_workers); /* Initialize the thread pool data structure */ @@ -135,22 +133,20 @@ xbt_parmap_t xbt_parmap_new(unsigned int num_workers, e_xbt_parmap_mode_t mode) /* Create the pool of worker threads */ xbt_parmap_thread_data_t data; parmap->workers[0] = NULL; -#ifdef CORE_BINDING - unsigned int core_bind = 0; +#ifdef HAVE_PTHREAD_SETAFFINITY + int core_bind = 0; #endif - for (i = 1; i < num_workers; i++) { + for (unsigned int i = 1; i < num_workers; i++) { data = xbt_new0(s_xbt_parmap_thread_data_t, 1); data->parmap = parmap; data->worker_id = i; - parmap->workers[i] = xbt_os_thread_create(NULL, xbt_parmap_worker_main, - data, NULL); -#ifdef CORE_BINDING + parmap->workers[i] = xbt_os_thread_create(NULL, xbt_parmap_worker_main, data, NULL); +#ifdef HAVE_PTHREAD_SETAFFINITY xbt_os_thread_bind(parmap->workers[i], core_bind); - if(core_bind!=xbt_os_get_numcores()){ + if (core_bind != xbt_os_get_numcores()) core_bind++; - } else { + else core_bind = 0; - } #endif } return parmap; diff --git a/src/xbt/xbt_os_thread.c b/src/xbt/xbt_os_thread.c index 98bfef2ee4..6b3d98a48b 100644 --- a/src/xbt/xbt_os_thread.c +++ b/src/xbt/xbt_os_thread.c @@ -8,6 +8,15 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "src/internal_config.h" +#ifdef HAVE_PTHREAD_SETAFFINITY +#define _GNU_SOURCE +#include +#endif + +#include +#include +#include #include #if defined(WIN32) @@ -19,26 +28,16 @@ #include #endif -#include "src/internal_config.h" #include "xbt/sysdep.h" #include "xbt/ex.h" -#include "src/xbt/ex_interface.h" /* We play crude games with exceptions */ +#include "src/xbt/ex_interface.h" /* We play crude games with exceptions */ #include "src/portable.h" -#include "xbt/xbt_os_time.h" /* Portable time facilities */ -#include "xbt/xbt_os_thread.h" /* This module */ -#include "src/xbt_modinter.h" /* Initialization/finalization of this module */ +#include "xbt/xbt_os_time.h" /* Portable time facilities */ +#include "xbt/xbt_os_thread.h" /* This module */ +#include "src/xbt_modinter.h" /* Initialization/finalization of this module */ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_sync_os, xbt, "Synchronization mechanism (OS-level)"); -/* ********************************* PTHREAD IMPLEMENTATION ************************************ */ -#include -#include -#include - -#ifdef CORE_BINDING -#define _GNU_SOURCE -#include -#endif /* use named sempahore when sem_init() does not work */ #ifndef HAVE_SEM_INIT @@ -182,18 +181,17 @@ xbt_os_thread_t xbt_os_thread_create(const char *name, pvoid_f_pvoid_t start_ro return res_thread; } - -#ifdef CORE_BINDING int xbt_os_thread_bind(xbt_os_thread_t thread, int cpu){ - pthread_t pthread = thread->t; int errcode = 0; +#ifdef HAVE_PTHREAD_SETAFFINITY + pthread_t pthread = thread->t; cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(cpu, &cpuset); errcode = pthread_setaffinity_np(pthread, sizeof(cpu_set_t), &cpuset); +#endif return errcode; } -#endif void xbt_os_thread_setstacksize(int stack_size) { diff --git a/tools/cmake/src/internal_config.h.in b/tools/cmake/src/internal_config.h.in index 0f4e9ad987..2ae3201872 100644 --- a/tools/cmake/src/internal_config.h.in +++ b/tools/cmake/src/internal_config.h.in @@ -82,13 +82,13 @@ #cmakedefine HAVE_SMPI @HAVE_SMPI@ /* Indicates that we have SMPI FORTRAN support */ -#cmakedefine SMPI_FORTRAN @SMPI_FORTRAN@ +#cmakedefine SMPI_FORTRAN @SMPI_FORTRAN@ /* We have mmap and objdump to handle privatization */ #cmakedefine HAVE_PRIVATIZATION @HAVE_PRIVATIZATION@ -/* Define if pthread_mutex_timedlock() is avaible or not (part of XPG6 standard only?) */ -#cmakedefine HAVE_MUTEX_TIMEDLOCK @HAVE_MUTEX_TIMEDLOCK@ +#cmakedefine HAVE_MUTEX_TIMEDLOCK @HAVE_MUTEX_TIMEDLOCK@ /* Seems to part of XPG6 standard only */ +#cmakedefine HAVE_PTHREAD_SETAFFINITY @HAVE_PTHREAD_SETAFFINITY@ /* Seems to be linux only */ /* Define to 1 if you have the `popen' function. */ #cmakedefine HAVE_POPEN @HAVE_POPEN@