From 03e7842112aeab1bd10811c2fc9be448aa1409eb Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Fri, 17 Aug 2018 15:07:34 +0200 Subject: [PATCH] Fix bindings verbosity when --smp-threads-per-core is used Now the execution summary and the nanox-bindings utility print correctly the bindings mask when one thread is bound to multiple CPUs. Also, the string is now more human readable, as binding is grouped by thread if such is the case. --- src/arch/smp/smpplugin.cpp | 86 +++++++++++++----------------- src/arch/smp/smpplugin_decl.hpp | 6 +-- src/core/system.cpp | 6 ++- src/support/smpbaseplugin_decl.hpp | 2 +- src/utils/nanox_bindings.cpp | 7 +-- 5 files changed, 47 insertions(+), 60 deletions(-) diff --git a/src/arch/smp/smpplugin.cpp b/src/arch/smp/smpplugin.cpp index 9fe913929..9580fa4b8 100644 --- a/src/arch/smp/smpplugin.cpp +++ b/src/arch/smp/smpplugin.cpp @@ -995,63 +995,49 @@ nanos::PE * smpProcessorFactory ( int id, int uid ) } } - /*! \brief returns a human readable string containing information about the binding mask, detecting ranks. - * format e.g., - * active[ i-j, m, o-p, ] - inactive[ k-l, n, ] + /*! \brief returns human readable strings containing the active and inactive masks + * + * The first value of the pair contains the active mask. + * The second value of the pair contains the inactive mask */ - std::string SMPPlugin::getBindingMaskString() const { - if ( _cpusByCpuId->empty() ) return ""; - - // inactive/active cpus list - std::ostringstream a, i; - - // Initialize rank limits with the first cpu in the list - int a0 = -1, aN = -1, i0 = -1, iN = -1; - SMPProcessor *first_cpu = _cpusByCpuId->begin()->second; - first_cpu->isActive() ? a0 = first_cpu->getBindingId() : i0 = first_cpu->getBindingId(); - - // Iterate through begin+1..end - std::map::iterator prev_it = _cpusByCpuId->begin(); /* begin() */ - std::map::iterator curr_it = prev_it; ++curr_it; /* begin() + 1 */ - while ( curr_it != _cpusByCpuId->end() ) { - /* Detect whether there is a state change (a->i/i->a). If so, - * close the rank and start a new one. If it's the last iteration - * close it anyway. - */ - SMPProcessor *prev = prev_it->second; - SMPProcessor *curr = curr_it->second; - if ( curr->isActive() && !prev->isActive() ) { - // change, i->a - iN = prev->getBindingId(); - a0 = curr->getBindingId(); - ( i0 != iN ) ? i << i0 << "-" << iN << ", " : i << i0 << ", "; - } else if ( !curr->isActive() && prev->isActive() ) { - // change, a->i - aN = prev->getBindingId(); - i0 = curr->getBindingId(); - ( a0 != aN ) ? a << a0 << "-" << aN << ", " : a << a0 << ", "; + std::pair SMPPlugin::getBindingStrings() const + { + CpuSet active, inactive; + std::string multiple; + bool multiple_binding = false; + for ( std::map::const_iterator it = _cpusByCpuId->begin(); + it != _cpusByCpuId->end(); ++it) { + SMPProcessor *cpu = it->second; + if ( cpu->isActive() ) { + // Append binding set to multiple string + CpuSet binding_list = cpu->getBindingList(); + if ( binding_list.size() > 1 ) { + multiple_binding = true; + multiple += "(" + binding_list.toString() + "), "; + } else { + multiple += binding_list.toString() + ", "; + } + + // Add to active cpuset + active.add( binding_list ); + } else { + // Add to inactive cpuset + inactive.add( cpu->getBindingList() ); } - ++prev_it; - ++curr_it; } - // close ranks and append strings according to the last cpu - SMPProcessor *last_cpu = prev_it->second; - if ( last_cpu->isActive() ) { - aN = last_cpu->getBindingId(); - ( a0 != aN ) ? a << a0 << "-" << aN << ", " : a << a0 << ", "; - } else { - iN = last_cpu->getBindingId(); - ( i0 != iN ) ? i << i0 << "-" << iN << ", " : i << i0 << ", "; + // remove last ', ' from the string multiple + if ( !multiple.empty() ) { + multiple.resize( multiple.size() - 2 ); } - // remove last comma - std::string sa = a.str(), si = i.str(); - if (!sa.empty()) sa.erase(sa.length()-2); - if (!si.empty()) si.erase(si.length()-2); + // construct return pair + std::pair strings; + strings.first = multiple_binding ? multiple : active.toString(); + strings.second = inactive.toString(); - return "active[ " + sa + " ] - inactive[ " + si + " ]"; - } + return strings; + } void SMPPlugin::applyCpuMask ( std::map &workers ) { diff --git a/src/arch/smp/smpplugin_decl.hpp b/src/arch/smp/smpplugin_decl.hpp index 076c1d721..dce84e501 100644 --- a/src/arch/smp/smpplugin_decl.hpp +++ b/src/arch/smp/smpplugin_decl.hpp @@ -205,11 +205,7 @@ class SMPPlugin : public SMPBasePlugin */ void createWorker( std::map &workers ); - /*! \brief returns a human readable string containing information about the binding mask, detecting ranks. - * format e.g., - * active[ i-j, m, o-p, ] - inactive[ k-l, n, ] - */ - virtual std::string getBindingMaskString() const; + virtual std::pair getBindingStrings() const; protected: diff --git a/src/core/system.cpp b/src/core/system.cpp index fc4385ee1..29e4d0169 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1382,6 +1382,10 @@ void System::environmentSummary() break; } + std::pair bindings = _smpPlugin->getBindingStrings(); + std::string system_cpus = + "active[ " + bindings.first + " ] - inactive[ " + bindings.second + " ]"; + std::ostringstream output; output << "Nanos++ Initial Environment Summary" << std::endl; output << "==========================================================" << std::endl; @@ -1389,7 +1393,7 @@ void System::environmentSummary() output << "=== Nanos++ version: " << PACKAGE_VERSION << std::endl; output << "=== PID: " << getpid() << std::endl; output << "=== Num. worker threads: " << _workers.size() << std::endl; - output << "=== System CPUs: " << _smpPlugin->getBindingMaskString() << std::endl; + output << "=== System CPUs: " << system_cpus << std::endl; output << "=== Binding: " << std::boolalpha << _smpPlugin->getBinding() << std::endl; output << "=== Prog. Model: " << prog_model << std::endl; output << "=== Priorities: " << (getPrioritiesNeeded() ? "Needed" : "Not needed") diff --git a/src/support/smpbaseplugin_decl.hpp b/src/support/smpbaseplugin_decl.hpp index d5f0e61db..b18089014 100644 --- a/src/support/smpbaseplugin_decl.hpp +++ b/src/support/smpbaseplugin_decl.hpp @@ -64,7 +64,7 @@ class SMPBasePlugin : public ArchPlugin { virtual int getRequestedWorkers() const = 0; virtual unsigned int getMaxWorkers() const = 0; virtual void createWorker( std::map &workers ) = 0; - virtual std::string getBindingMaskString() const = 0; + virtual std::pair getBindingStrings() const = 0; virtual bool asyncTransfersEnabled() const = 0; }; diff --git a/src/utils/nanox_bindings.cpp b/src/utils/nanox_bindings.cpp index a08ab6ad0..57c4a5789 100644 --- a/src/utils/nanox_bindings.cpp +++ b/src/utils/nanox_bindings.cpp @@ -98,13 +98,14 @@ int main( int argc, char *argv[] ) pid_t pid = getpid(); - const CpuSet& cpu_set = do_all ? sys.getCpuProcessMask() : sys.getCpuActiveMask(); - char hostname[HOST_NAME_MAX]; gethostname( hostname, HOST_NAME_MAX ); std::cout << "Nanos++: " << hostname << "::" << pid - << " [ " << cpu_set.toString() << " ]" << std::endl; + << " [ " << ( do_all ? + sys.getCpuProcessMask().toString() : + sys.getSMPPlugin()->getBindingStrings().first ) + << " ]" << std::endl; exit( EXIT_SUCCESS ); } -- GitLab