Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85864 - in trunk: boost/thread boost/thread/detail libs/thread/doc libs/thread/src/pthread libs/thread/src/win32 libs/thread/test
From: tim_at_[hidden]
Date: 2013-09-24 02:41:24


Author: timblechmann
Date: 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013)
New Revision: 85864
URL: http://svn.boost.org/trac/boost/changeset/85864

Log:
thread: implement physical_concurrency

Added:
   trunk/libs/thread/test/test_physical_concurrency.cpp (contents, props changed)
Text files modified:
   trunk/boost/thread/detail/thread.hpp | 1
   trunk/boost/thread/scoped_thread.hpp | 6 +++
   trunk/libs/thread/doc/scoped_thread.qbk | 15 ++++++++++
   trunk/libs/thread/doc/thread_ref.qbk | 16 ++++++++++
   trunk/libs/thread/src/pthread/thread.cpp | 59 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/thread/src/win32/thread.cpp | 25 ++++++++++++++++
   trunk/libs/thread/test/Jamfile.v2 | 1
   trunk/libs/thread/test/test_physical_concurrency.cpp | 24 ++++++++++++++++
   8 files changed, 145 insertions(+), 2 deletions(-)

Modified: trunk/boost/thread/detail/thread.hpp
==============================================================================
--- trunk/boost/thread/detail/thread.hpp Tue Sep 24 01:35:11 2013 (r85863)
+++ trunk/boost/thread/detail/thread.hpp 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013) (r85864)
@@ -546,6 +546,7 @@
         void detach();
 
         static unsigned hardware_concurrency() BOOST_NOEXCEPT;
+ static unsigned physical_concurrency() BOOST_NOEXCEPT;
 
 #define BOOST_THREAD_DEFINES_THREAD_NATIVE_HANDLE
         typedef detail::thread_data_base::native_handle_type native_handle_type;

Modified: trunk/boost/thread/scoped_thread.hpp
==============================================================================
--- trunk/boost/thread/scoped_thread.hpp Tue Sep 24 01:35:11 2013 (r85863)
+++ trunk/boost/thread/scoped_thread.hpp 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013) (r85864)
@@ -261,11 +261,15 @@
     }
 #endif
 
- static unsigned hardware_concurrency()BOOST_NOEXCEPT
+ static unsigned hardware_concurrency() BOOST_NOEXCEPT
     {
       return thread::hardware_concurrency();
     }
 
+ static unsigned physical_concurrency() BOOST_NOEXCEPT
+ {
+ return thread::physical_concurrency();
+ }
   };
 
   /**

Modified: trunk/libs/thread/doc/scoped_thread.qbk
==============================================================================
--- trunk/libs/thread/doc/scoped_thread.qbk Tue Sep 24 01:35:11 2013 (r85863)
+++ trunk/libs/thread/doc/scoped_thread.qbk 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013) (r85864)
@@ -216,6 +216,7 @@
         void detach();
 
         static unsigned hardware_concurrency() noexcept;
+ static unsigned physical_concurrency() noexcept;
 
         typedef thread::native_handle_type native_handle_type;
         native_handle_type native_handle();
@@ -458,6 +459,20 @@
 
 [endsect]
 
+
+[section:physical_concurrency Static member function `physical_concurrency()`]
+
+ unsigned physical_concurrency() noexecpt;
+
+[variablelist
+
+[[Effects:] [Equivalent to return `thread::physical_concurrency()`.]]
+
+]
+
+[endsect]
+
+
 [section:nativehandle Member function `native_handle()`]
 
     typedef thread::native_handle_type native_handle_type;

Modified: trunk/libs/thread/doc/thread_ref.qbk
==============================================================================
--- trunk/libs/thread/doc/thread_ref.qbk Tue Sep 24 01:35:11 2013 (r85863)
+++ trunk/libs/thread/doc/thread_ref.qbk 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013) (r85864)
@@ -470,6 +470,7 @@
         void detach();
 
         static unsigned hardware_concurrency() noexcept;
+ static unsigned physical_concurrency() noexcept;
 
         typedef platform-specific-type native_handle_type;
         native_handle_type native_handle();
@@ -991,6 +992,21 @@
 
 [endsect]
 
+[section:physical_concurrency Static member function `physical_concurrency()`]
+
+ unsigned physical_concurrency() noexecpt;
+
+[variablelist
+
+[[Returns:] [The number of physical cores available on the current system. In contrast to `hardware_concurrency()` it does not return
+ the number of virtual cores, but it counts only physical cores.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
 [section:nativehandle Member function `native_handle()`]
 
     typedef platform-specific-type native_handle_type;

Modified: trunk/libs/thread/src/pthread/thread.cpp
==============================================================================
--- trunk/libs/thread/src/pthread/thread.cpp Tue Sep 24 01:35:11 2013 (r85863)
+++ trunk/libs/thread/src/pthread/thread.cpp 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013) (r85864)
@@ -27,6 +27,15 @@
 #include <unistd.h>
 #endif
 
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <fstream>
+#include <string>
+#include <set>
+#include <vector>
+
 #include "./timeconv.inl"
 
 namespace boost
@@ -543,6 +552,56 @@
 #endif
     }
 
+ unsigned thread::physical_concurrency() BOOST_NOEXCEPT
+ {
+#ifdef __linux__
+ try {
+ using namespace std;
+
+ ifstream proc_cpuinfo ("/proc/cpuinfo");
+
+ unsigned current_processor = 0;
+ const string physical_id("physical id"), core_id("core id");
+
+ typedef std::pair<unsigned, unsigned> core_entry; // [physical ID, core id]
+
+ std::set<core_entry> cores;
+
+ core_entry current_core_entry;
+
+ for (string line; getline(proc_cpuinfo, line); ) {
+ vector<string> key_val(2);
+ boost::split(key_val, line, boost::is_any_of(":"));
+
+ string key = key_val[0];
+ string value = key_val[1];
+ boost::trim(key);
+ boost::trim(value);
+
+ if (key == physical_id) {
+ current_core_entry.first = boost::lexical_cast<unsigned>(value);
+ continue;
+ }
+
+ if (key == core_id) {
+ current_core_entry.second = boost::lexical_cast<unsigned>(value);
+ cores.insert(current_core_entry);
+ continue;
+ }
+ }
+ return cores.size();
+ } catch(...) {
+ return 0;
+ }
+#elif defined(__APPLE__)
+ int count;
+ size_t size=sizeof(count);
+ return sysctlbyname("hw.physicalcpu",&count,&size,NULL,0)?0:count;
+#else
+ return hardware_concurrency();
+#endif
+ }
+
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
     void thread::interrupt()
     {

Modified: trunk/libs/thread/src/win32/thread.cpp
==============================================================================
--- trunk/libs/thread/src/win32/thread.cpp Tue Sep 24 01:35:11 2013 (r85863)
+++ trunk/libs/thread/src/win32/thread.cpp 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013) (r85864)
@@ -407,6 +407,8 @@
         return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0);
     }
 
+#endif
+
     unsigned thread::hardware_concurrency() BOOST_NOEXCEPT
     {
         //SYSTEM_INFO info={{0}};
@@ -414,7 +416,28 @@
         GetSystemInfo(&info);
         return info.dwNumberOfProcessors;
     }
-#endif
+
+ unsigned thread::physical_concurrency() BOOST_NOEXCEPT
+ {
+ unsigned cores = 0;
+ DWORD size = 0;
+
+ GetLogicalProcessorInformation(NULL, &size);
+ if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
+ return 0;
+
+ std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(size);
+ if (GetLogicalProcessorInformation(buffer.data(), &size) == FALSE)
+ return 0;
+
+ const size_t Elements = size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
+
+ for (size_t i = 0; i < Elements; ++i) {
+ if (buffer[i].Relationship == RelationProcessorCore)
+ ++cores;
+ }
+ return cores;
+ }
 
     thread::native_handle_type thread::native_handle()
     {

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 Tue Sep 24 01:35:11 2013 (r85863)
+++ trunk/libs/thread/test/Jamfile.v2 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013) (r85864)
@@ -209,6 +209,7 @@
           [ thread-test test_thread.cpp ]
           [ thread-test test_thread_id.cpp ]
           [ thread-test test_hardware_concurrency.cpp ]
+ [ thread-test test_physical_concurrency.cpp ]
           [ thread-test test_thread_move.cpp ]
           [ thread-test test_thread_return_local.cpp ]
           [ thread-test test_thread_move_return.cpp ]

Added: trunk/libs/thread/test/test_physical_concurrency.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/thread/test/test_physical_concurrency.cpp 2013-09-24 02:41:24 EDT (Tue, 24 Sep 2013) (r85864)
@@ -0,0 +1,24 @@
+// Copyright (C) 2007 Anthony Williams
+// Copyright (C) 2013 Tim Blechmann
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+
+void test_physical_concurrency_is_non_zero()
+{
+ BOOST_CHECK(boost::thread::physical_concurrency()!=0);
+}
+
+boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
+{
+ boost::unit_test::test_suite* test =
+ BOOST_TEST_SUITE("Boost.Threads: physical concurrency test suite");
+
+ test->add(BOOST_TEST_CASE(test_physical_concurrency_is_non_zero));
+ return test;
+}
+
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk