[llvm] r314809 - Use sched_getaffinity instead of std::thread::hardware_concurrency.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 09:25:15 PDT 2017


Author: rafael
Date: Tue Oct  3 09:25:15 2017
New Revision: 314809

URL: http://llvm.org/viewvc/llvm-project?rev=314809&view=rev
Log:
Use sched_getaffinity instead of std::thread::hardware_concurrency.

The issue with std::thread::hardware_concurrency is that it forwards
to libc and some implementations (like glibc) don't take thread
affinity into consideration.

With this change a llvm program that can execute in only 2 cores will
use 2 threads, even if the machine has 32 cores.

This makes benchmarking a lot easier, but should also help if someone
doesn't want to use all cores for compilation for example.

Modified:
    llvm/trunk/cmake/config-ix.cmake
    llvm/trunk/include/llvm/Config/config.h.cmake
    llvm/trunk/include/llvm/Support/ThreadPool.h
    llvm/trunk/include/llvm/Support/Threading.h
    llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp
    llvm/trunk/lib/Support/Parallel.cpp
    llvm/trunk/lib/Support/ThreadPool.cpp
    llvm/trunk/lib/Support/Threading.cpp
    llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp

Modified: llvm/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/cmake/config-ix.cmake (original)
+++ llvm/trunk/cmake/config-ix.cmake Tue Oct  3 09:25:15 2017
@@ -269,6 +269,7 @@ if( LLVM_USING_GLIBC )
   add_definitions( -D_GNU_SOURCE )
 endif()
 # This check requires _GNU_SOURCE
+check_library_exists(c sched_getaffinity "" HAVE_SCHED_GETAFFINITY)
 if(HAVE_LIBPTHREAD)
   check_library_exists(pthread pthread_getname_np "" HAVE_PTHREAD_GETNAME_NP)
   check_library_exists(pthread pthread_setname_np "" HAVE_PTHREAD_SETNAME_NP)

Modified: llvm/trunk/include/llvm/Config/config.h.cmake
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Config/config.h.cmake (original)
+++ llvm/trunk/include/llvm/Config/config.h.cmake Tue Oct  3 09:25:15 2017
@@ -185,6 +185,9 @@
 /* Define to 1 if you have the `setenv' function. */
 #cmakedefine HAVE_SETENV ${HAVE_SETENV}
 
+/* Define to 1 if you have the `sched_getaffinity' function. */
+#cmakedefine HAVE_SCHED_GETAFFINITY ${HAVE_SCHED_GETAFFINITY}
+
 /* Define to 1 if you have the `setrlimit' function. */
 #cmakedefine HAVE_SETRLIMIT ${HAVE_SETRLIMIT}
 

Modified: llvm/trunk/include/llvm/Support/ThreadPool.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ThreadPool.h?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ThreadPool.h (original)
+++ llvm/trunk/include/llvm/Support/ThreadPool.h Tue Oct  3 09:25:15 2017
@@ -38,8 +38,8 @@ public:
   using TaskTy = std::function<void()>;
   using PackagedTaskTy = std::packaged_task<void()>;
 
-  /// Construct a pool with the number of core available on the system (or
-  /// whatever the value returned by std::thread::hardware_concurrency() is).
+  /// Construct a pool with the number of threads found by
+  /// hardware_concurrency().
   ThreadPool();
 
   /// Construct a pool of \p ThreadCount threads

Modified: llvm/trunk/include/llvm/Support/Threading.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Threading.h?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Threading.h (original)
+++ llvm/trunk/include/llvm/Support/Threading.h Tue Oct  3 09:25:15 2017
@@ -131,6 +131,14 @@ void llvm_execute_on_thread(void (*UserF
   /// Returns 1 when LLVM is configured with LLVM_ENABLE_THREADS=OFF
   unsigned heavyweight_hardware_concurrency();
 
+  /// Get the number of threads that the current program can execute
+  /// concurrently. On some systems std::thread::hardware_concurrency() returns
+  /// the total number of cores, without taking affinity into consideration.
+  /// Returns 1 when LLVM is configured with LLVM_ENABLE_THREADS=OFF.
+  /// Fallback to std::thread::hardware_concurrency() if sched_getaffinity is
+  /// not available.
+  unsigned hardware_concurrency();
+
   /// \brief Return the current thread id, as used in various OS system calls.
   /// Note that not all platforms guarantee that the value returned will be
   /// unique across the entire system, so portable code should not assume

Modified: llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp Tue Oct  3 09:25:15 2017
@@ -195,15 +195,7 @@ void PrintPC(const char *SymbolizedFMT,
     Printf(FallbackFMT, PC);
 }
 
-unsigned NumberOfCpuCores() {
-  unsigned N = std::thread::hardware_concurrency();
-  if (!N) {
-    Printf("WARNING: std::thread::hardware_concurrency not well defined for "
-           "your platform. Assuming CPU count of 1.\n");
-    N = 1;
-  }
-  return N;
-}
+unsigned NumberOfCpuCores() { return hardware_concurrency(); }
 
 size_t SimpleFastHash(const uint8_t *Data, size_t Size) {
   size_t Res = 0;

Modified: llvm/trunk/lib/Support/Parallel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Parallel.cpp?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Parallel.cpp (original)
+++ llvm/trunk/lib/Support/Parallel.cpp Tue Oct  3 09:25:15 2017
@@ -9,6 +9,7 @@
 
 #include "llvm/Support/Parallel.h"
 #include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Threading.h"
 
 #include <atomic>
 #include <stack>
@@ -70,8 +71,7 @@ Executor *Executor::getDefaultExecutor()
 ///   in filo order.
 class ThreadPoolExecutor : public Executor {
 public:
-  explicit ThreadPoolExecutor(
-      unsigned ThreadCount = std::thread::hardware_concurrency())
+  explicit ThreadPoolExecutor(unsigned ThreadCount = hardware_concurrency())
       : Done(ThreadCount) {
     // Spawn all but one of the threads in another thread as spawning threads
     // can take a while.

Modified: llvm/trunk/lib/Support/ThreadPool.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ThreadPool.cpp?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/lib/Support/ThreadPool.cpp (original)
+++ llvm/trunk/lib/Support/ThreadPool.cpp Tue Oct  3 09:25:15 2017
@@ -14,14 +14,15 @@
 #include "llvm/Support/ThreadPool.h"
 
 #include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Threading.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
 #if LLVM_ENABLE_THREADS
 
-// Default to std::thread::hardware_concurrency
-ThreadPool::ThreadPool() : ThreadPool(std::thread::hardware_concurrency()) {}
+// Default to hardware_concurrency
+ThreadPool::ThreadPool() : ThreadPool(hardware_concurrency()) {}
 
 ThreadPool::ThreadPool(unsigned ThreadCount)
     : ActiveThreads(0), EnableFlag(true) {

Modified: llvm/trunk/lib/Support/Threading.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Threading.cpp?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Threading.cpp (original)
+++ llvm/trunk/lib/Support/Threading.cpp Tue Oct  3 09:25:15 2017
@@ -47,6 +47,8 @@ void llvm::llvm_execute_on_thread(void (
 
 unsigned llvm::heavyweight_hardware_concurrency() { return 1; }
 
+unsigned llvm::hardware_concurrency() { return 1; }
+
 uint64_t llvm::get_threadid() { return 0; }
 
 uint32_t llvm::get_max_thread_name_length() { return 0; }
@@ -71,6 +73,18 @@ unsigned llvm::heavyweight_hardware_conc
   return NumPhysical;
 }
 
+unsigned llvm::hardware_concurrency() {
+#ifdef HAVE_SCHED_GETAFFINITY
+  cpu_set_t Set;
+  if (sched_getaffinity(0, sizeof(Set), &Set))
+    return CPU_COUNT(&Set);
+#endif
+  // Guard against std::thread::hardware_concurrency() returning 0.
+  if (unsigned Val = std::thread::hardware_concurrency())
+    return Val;
+  return 1;
+}
+
 // Include the platform-specific parts of this class.
 #ifdef LLVM_ON_UNIX
 #include "Unix/Threading.inc"

Modified: llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp?rev=314809&r1=314808&r2=314809&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp (original)
+++ llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp Tue Oct  3 09:25:15 2017
@@ -211,8 +211,8 @@ static void mergeInstrProfile(const Weig
 
   // If NumThreads is not specified, auto-detect a good default.
   if (NumThreads == 0)
-    NumThreads = std::max(1U, std::min(std::thread::hardware_concurrency(),
-                                       unsigned(Inputs.size() / 2)));
+    NumThreads =
+        std::min(hardware_concurrency(), unsigned((Inputs.size() + 1) / 2));
 
   // Initialize the writer contexts.
   SmallVector<std::unique_ptr<WriterContext>, 4> Contexts;




More information about the llvm-commits mailing list