13 #include "threadpool.h" 31 ss << std::fixed << std::setprecision(3);
38 virtual void dispatch(
SystemRoot const & ) = 0;
39 virtual void dispatch(
Socket* ) = 0;
40 virtual void dispatch(
Core* ) = 0;
48 std::stringstream ss{};
54 virtual void accept(
Visitor & v ) = 0;
66 HyperThread(
PCM* m, int32 threadID, int32 osID,
enum Status status ) : pcm_(m), threadID_(threadID), osID_(osID), status_(status) {}
69 virtual void accept(
Visitor& v )
override {
76 ccs.BasicCounterState::readAndAggregate( msrHandle_ );
80 void addMSRHandle( std::shared_ptr<SafeMsrHandle> handle ) {
84 int32 threadID()
const {
93 std::shared_ptr<SafeMsrHandle> msrHandle()
const {
97 bool isOnline()
const {
98 return (status_ == Status::Online);
103 std::shared_ptr<SafeMsrHandle> msrHandle_;
111 constexpr
static int32 MAX_THREADS_PER_CORE = 4;
114 Core(
PCM* m, int32 coreID, int32 tileID, int32 socketID ) {
118 socketID_ = socketID;
122 for (
auto& thread : threads_ )
126 virtual void accept(
Visitor& v )
override {
134 ccs += thread->coreCounterState();
139 void addHyperThreadInfo( int32 threadID, int32 osID ) {
140 if ( threadID >= MAX_THREADS_PER_CORE ) {
141 std::stringstream ss;
142 ss <<
"ERROR: Core: threadID cannot be larger than " << MAX_THREADS_PER_CORE <<
".\n";
143 throw std::runtime_error( ss.str() );
145 if ( threads_.size() == 0 ||
146 std::find_if( threads_.begin(), threads_.end(),
148 return ht->osID() == osID;
150 ) == threads_.end() )
153 threads_.push_back(
new HyperThread( pcm_, threadID, osID, Status::Online ) );
157 HyperThread* hyperThread(
size_t threadNo )
const {
158 if ( threadNo >= threads_.size() )
159 throw std::runtime_error(
"ERROR: hyperThread: threadNo larger than vector." );
160 return threads_[ threadNo ];
165 if ( thread->osID() == osID )
171 std::vector<HyperThread*> threads()
const {
175 std::shared_ptr<SafeMsrHandle> msrHandle()
const {
176 if ( 0 == threads_.size() )
177 throw std::runtime_error(
"BUG: No threads yet but asking for a msrHandle!");
178 return threads_.front()->msrHandle();
181 int32 coreID()
const {
185 int32 tileID()
const {
189 int32 socketID()
const {
193 bool isOnline()
const {
194 for(
auto& thread : threads_ )
195 if ( thread->isOnline() )
202 std::vector<HyperThread*> threads_;
211 Uncore(
PCM* m, int32 socketID ) : pcm_( m ), refCore_(
nullptr ), socketID_( socketID ) {}
217 virtual void accept(
Visitor& v ) = 0;
221 Core* refCore()
const {
222 if ( refCore_ ==
nullptr )
223 throw std::runtime_error(
"BUG: Uncore: refCore was never set!" );
227 int32 socketID()
const {
231 void setRefCore(
Core* refCore ) {
247 virtual void accept(
Visitor& v )
override {
260 virtual void accept(
Visitor& v )
override {
275 Socket(
PCM* m, int32 apicID, int32 logicalID );
278 for (
auto& core : cores_ )
284 virtual void accept(
Visitor& v )
override {
288 void addCore(
Core* c ) {
289 cores_.push_back( c );
294 for (
Core* core : cores_ ) {
295 thread = core->findThreadByOSID(osID);
296 if (
nullptr != thread )
303 if ( cores_.size() == 0 )
304 throw std::runtime_error(
"No cores added to the socket so cannot set reference core");
305 refCore_ = cores_.front();
307 uncore_->setRefCore( refCore_ );
312 Core* findCoreByTileID( int32 tileID ) {
313 for (
auto& core : cores_ ) {
314 if ( core->tileID() == tileID )
320 std::vector<Core*>
const & cores(
void )
const {
324 Uncore* uncore(
void )
const {
328 int32 apicId()
const {
332 int32 socketID()
const {
336 bool isOnline()
const {
337 return refCore_->isOnline();
341 std::vector<Core*> cores_;
358 for (
auto& socket : sockets_ )
360 for (
auto& thread : offlinedThreadsAtStart_ )
364 virtual void accept(
Visitor& v )
override {
368 void addSocket( int32 apic_id, int32 logical_id ) {
370 sockets_.push_back( s );
377 bool entryAdded =
false;
378 for (
auto& socket : sockets_ ) {
379 if ( socket->apicId() == te.socket ) {
380 Core* core =
nullptr;
381 if ( (core = socket->findCoreByTileID( te.tile_id )) ==
nullptr ) {
383 core =
new Core( pcm_, te.core_id, te.tile_id, te.socket );
385 core->addHyperThreadInfo( te.thread_id, osID );
386 socket->addCore( core );
390 core->addHyperThreadInfo( te.thread_id, osID );
400 offlinedThreadsAtStart_.push_back(
new HyperThread( pcm_, -1, osID, Status::Offline ) );
406 for (
Socket* socket : sockets_ ) {
407 thread = socket->findThreadByOSID( osID );
408 if (
nullptr != thread )
412 if ( ht->osID() == osID )
417 void addMSRHandleToOSThread( std::shared_ptr<SafeMsrHandle> handle, uint32 osID )
421 if (
nullptr == thread )
422 throw std::runtime_error(
"SystemRoot::addMSRHandleToOSThread osID not found" );
423 thread->addMSRHandle( handle );
430 for (
auto& socket : sockets_ ) {
431 scs += ( socket->socketCounterState() );
436 std::vector<Socket*>
const & sockets(
void )
const {
440 std::vector<HyperThread*>
const & offlinedThreadsAtStart(
void )
const {
441 return offlinedThreadsAtStart_;
445 std::vector<Socket*> sockets_;
446 std::vector<HyperThread*> offlinedThreadsAtStart_;
462 virtual void dispatch(
SystemRoot const& syp )
override;
464 virtual void dispatch(
Socket* sop )
override {
467 for (
auto* core : sop->cores() )
468 core->accept( *
this );
472 DBG( 3,
"Lambda fetching UncoreCounterState async" );
474 if ( !s->isOnline() )
476 return s->uncore()->uncoreCounterState();
479 ucsFutures_[ sop->socketID() ] = job->getFuture();
485 virtual void dispatch(
Core* cop )
override {
488 for (
auto* thread : cop->threads() ) {
490 thread->accept( *
this );
494 virtual void dispatch(
HyperThread* htp )
override {
499 DBG( 3,
"Lambda fetching CoreCounterState async" );
501 if ( !h->isOnline() )
503 return h->coreCounterState();
506 ccsFutures_[ htp->osID() ] = job->getFuture();
518 std::vector<CoreCounterState>
const & coreCounterStates(
void )
const {
522 std::vector<SocketCounterState>
const & socketCounterStates(
void )
const {
530 std::chrono::steady_clock::time_point dispatchedAt(
void )
const {
531 return dispatchedAt_;
535 std::vector<CoreCounterState> ccsVector_;
536 std::vector<SocketCounterState> socsVector_;
538 std::vector<std::future<CoreCounterState>> ccsFutures_;
539 std::vector<std::future<UncoreCounterState>> ucsFutures_;
540 std::chrono::steady_clock::time_point dispatchedAt_{};
Internal type and constant definitions.
(Logical) core-wide counter state
Definition: cpucounters.h:2925
Definition: threadpool.h:107
Definition: topology.h:349
Definition: topology.h:208
Socket-wide counter state.
Definition: cpucounters.h:2938
Definition: topology.h:63
Definition: topology.h:254
CPU Performance Monitor.
Definition: cpucounters.h:543
Main CPU counters header.
Definition: threadpool.h:25
Definition: topology.h:241
Definition: topology.h:455
Definition: topology.h:27
System-wide counter state.
Definition: cpucounters.h:2978
Definition: topology.h:271
Definition: topology.h:109
Definition: topology.h:51
Basic uncore counter state.
Definition: cpucounters.h:2678
Definition: cpucounters.h:87