Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
try to bind worker threads to cores when possible
authorMartin Quinson <martin.quinson@loria.fr>
Sat, 5 Mar 2016 22:21:05 +0000 (23:21 +0100)
committerMartin Quinson <martin.quinson@loria.fr>
Sat, 5 Mar 2016 22:21:14 +0000 (23:21 +0100)
CMakeLists.txt
include/xbt/xbt_os_thread.h
src/xbt/parmap.cpp
src/xbt/xbt_os_thread.c
tools/cmake/src/internal_config.h.in

index 152eb96..dfd7569 100644 (file)
@@ -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()
index 3891cc8..3d95429 100644 (file)
@@ -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);
index d3edb7b..88431cc 100644 (file)
@@ -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;
index 98bfef2..6b3d98a 100644 (file)
@@ -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 <sched.h>
+#endif
+
+#include <pthread.h>
+#include <limits.h>
+#include <semaphore.h>
 #include <errno.h>
 
 #if defined(WIN32)
 #include <unistd.h>
 #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 <pthread.h>
-#include <limits.h>
-#include <semaphore.h>
-
-#ifdef CORE_BINDING
-#define _GNU_SOURCE
-#include <sched.h>
-#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)
 {
index 0f4e9ad..2ae3201 100644 (file)
 #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@