46 friend class StateTimerPool;
50 typedef uint32_t TimerId;
51 typedef std::shared_ptr<StateTimer> Handle;
52 typedef std::shared_ptr<std::unordered_map<uint32_t, uint32_t>> StateSetInfo;
60 template<
class EnumClassT>
63 uint32_t state_set_hash_code;
65 uint32_t active_state_in_set;
66 std::shared_ptr<StateSet> state_set;
70 state_set_hash_code =
typeid(EnumClassT).hash_code();
71 state_index =
static_cast<uint32_t
>(state_enum);
74 auto it = state_set_map_.find(state_set_hash_code);
76 "Can not find state enum class in timer.");
77 state_set = it->second;
79 if (state_set->active_state_index_.isValid())
81 active_state_in_set = state_set->active_state_index_.getValue();
83 "State aleady started");
85 "Wrong active state starting time.");
88 endTimerState_(state_set);
92 sparta_assert(state_index < state_set->state_set_delta_.size(),
93 "State enum out of range.")
94 state_set->active_state_index_ = state_index;
95 state_set->active_state_starting_time_ = clk_->
currentCycle();
102 template<
class EnumClassT>
105 uint32_t state_set_hash_code;
106 uint32_t state_index;
107 int32_t active_state_in_set;
108 std::shared_ptr<StateSet> state_set;
112 state_set_hash_code =
typeid(EnumClassT).hash_code();
113 state_index =
static_cast<uint32_t
>(state_enum);
116 auto it = state_set_map_.find(state_set_hash_code);
118 "Can not find state enum class in timer.");
119 state_set = it->second;
123 "No active state in the set when endState.");
124 active_state_in_set = state_set->active_state_index_.getValue();
126 "State does not match active state in the set when endState.");
129 endTimerState_(state_set);
131 state_set->active_state_index_.clearValid();
132 state_set->active_state_starting_time_ = 0;
140 template<
class EnumClassT>
157 sparta::Clock::Cycle active_state_starting_time_;
159 std::vector<sparta::Clock::Cycle> state_set_delta_;
161 StateSet(uint32_t num_state):
162 active_state_starting_time_(0),
163 state_set_delta_(std::vector<
sparta::
Clock::Cycle>(num_state, 0))
182 StateSetInfo state_set_info_map_ptr,
183 StateTimerUnit * state_timer_unit_ptr):
186 state_timer_unit_ptr_(state_timer_unit_ptr),
190 for (
auto it = state_set_info_map_ptr->begin(); it != state_set_info_map_ptr->end(); ++it)
192 state_set_map_.insert(std::map<uint32_t, std::shared_ptr<StateSet>>::value_type
193 (it->first, std::shared_ptr<StateSet>(
new StateSet(it->second))));
201 void endTimerState_(std::shared_ptr<StateSet> &state_set)
203 uint32_t active_state_in_set = state_set->active_state_index_.getValue();
204 if (state_set->active_state_starting_time_ > last_query_time_)
206 state_set->state_set_delta_[active_state_in_set] +=
207 clk_->
currentCycle() - state_set->active_state_starting_time_;
211 state_set->state_set_delta_[active_state_in_set] +=
220 void queryStateTimer_();
226 void releaseStateTimer_();
235 CustomDeleter(
const std::weak_ptr<StateTimerPool> & pool_ptr):
236 state_timer_pool_ptr_(pool_ptr)
239 void operator()(StateTimer *ptr)
241 if(!state_timer_pool_ptr_.expired())
243 ptr->releaseStateTimer_();
247 std::weak_ptr<StateTimerPool> state_timer_pool_ptr_;
255 StateTimerUnit * state_timer_unit_ptr_;
257 std::unordered_map<uint32_t, std::shared_ptr<StateSet>> state_set_map_;
259 sparta::Clock::Cycle last_query_time_;
275 template<
class... ArgsT>
277 std::string state_timer_unit_name,
278 std::string description,
279 uint32_t num_timer_init,
287 state_timer_pool_ptr_->releaseAllActiveTimer();
296 return state_timer_pool_ptr_->allocateTimer();
304 state_timer_pool_ptr_->queryAllActiveTimer();
305 return state_timer_histogram_ptr_->getDisplayStringCumulativeAllState();
311 template<
class EnumClassT>
314 uint32_t state_set_hash_code;
315 uint32_t state_index;
317 state_set_hash_code =
typeid(EnumClassT).hash_code();
318 state_index =
static_cast<uint32_t
>(state_enum);
320 state_timer_pool_ptr_->queryAllActiveTimer();
321 return state_timer_histogram_ptr_->getDisplayStringCumulativeOneState(state_set_hash_code, state_index);
345 StateTimer::StateSetInfo state_set_info_map_ptr,
347 uint32_t num_state_timer_init);
353 StateTimer::Handle allocateTimer()
355 StateTimer::TimerId timer_id;
357 if(available_timer_vec_ptr_->size()==0)
360 uint32_t current_num_timer = timer_list_ptr_->size();
362 "No timer available, pool exceeds MAX capacity.")
363 std::cout << "Warining: "<< current_num_timer <<
364 " StateTimers are inflight, creating more." << std::endl;
365 for (uint32_t i = current_num_timer; i < current_num_timer + num_state_timer_init_; i++)
367 timer_list_ptr_->push_back(StateTimer::Handle
368 (
new StateTimer(clk_, i, state_set_info_map_ptr_, state_timer_unit_ptr_)));
369 available_timer_vec_ptr_->push_back(std::make_pair(i, timer_list_ptr_->at(i)));
371 sparta_assert(current_num_timer + num_state_timer_init_ == timer_list_ptr_->size(),
372 "Number of Timers created does not add up.")
375 timer_id = available_timer_vec_ptr_->back().first;
376 active_timer_map_ptr_->insert(std::map<StateTimer::TimerId, StateTimer::Handle>::value_type
377 (timer_id, available_timer_vec_ptr_->back().second));
378 available_timer_vec_ptr_->pop_back();
379 sparta_assert(active_timer_map_ptr_->size() + available_timer_vec_ptr_->size()
380 == timer_list_ptr_->size(),
"Number of Timers does not add up.")
381 return StateTimer::Handle(timer_list_ptr_->at(timer_id).get(), StateTimer::CustomDeleter(my_life_));
388 void releaseTimer(StateTimer::TimerId timer_id)
391 auto it = active_timer_map_ptr_->find(timer_id);
393 "Timer not in active timer map when release. ");
394 available_timer_vec_ptr_->push_back(std::make_pair(timer_id, it->second));
395 active_timer_map_ptr_->erase(it);
396 sparta_assert(active_timer_map_ptr_->size() + available_timer_vec_ptr_->size()
397 == timer_list_ptr_->size(),
"Number of Timers does not add up.")
403 void queryAllActiveTimer();
408 void releaseAllActiveTimer();
413 std::unique_ptr<std::vector<StateTimer::Handle>> timer_list_ptr_;
415 std::unique_ptr<std::unordered_map<StateTimer::TimerId, StateTimer::Handle>>
416 active_timer_map_ptr_;
418 std::unique_ptr<std::vector<std::pair<StateTimer::TimerId, StateTimer::Handle>>>
419 available_timer_vec_ptr_;
421 std::shared_ptr<StateTimerPool> my_life_;
423 uint32_t num_state_timer_init_;
425 StateTimer::StateSetInfo state_set_info_map_ptr_;
429 StateTimerUnit * state_timer_unit_ptr_;
431 const uint32_t MAX_NUM_STATETIMER = 10000;
439 class StateTimerHistogram
458 StateTimerHistogram(TreeNode * parent,
459 std::string state_timer_unit_name,
460 std::unordered_map<uint32_t, std::string> state_set_name_map,
461 StateTimerDataContainerPtr state_timer_data_container_ptr,
462 StateTimer::StateSetInfo state_set_info_map_ptr,
463 uint32_t lower, uint32_t upper, uint32_t bin_size):
464 state_timer_data_container_ptr_(state_timer_data_container_ptr)
467 for (
auto it = state_set_info_map_ptr->begin(); it != state_set_info_map_ptr->end(); ++it)
469 std::shared_ptr<std::vector<std::shared_ptr<sparta::Histogram>>>
470 histogram_vector(
new std::vector<std::shared_ptr<sparta::Histogram>>);
471 for (uint32_t i = 0; i < it->second; i++)
473 histogram_vector->push_back(std::shared_ptr<sparta::Histogram>
475 state_timer_unit_name +
"_histogram_set_" + state_set_name_map[it->first] +
476 "_state_" + std::to_string(i),
"state timer histogram" ,
477 lower, upper , bin_size)));
479 timer_histogram_map_.insert(std::unordered_map<uint32_t,
480 std::shared_ptr<std::vector<std::shared_ptr<sparta::Histogram>>>>::value_type
481 (it->first, histogram_vector));
488 void updateHistogram()
490 for (
auto it = timer_histogram_map_.begin(); it != timer_histogram_map_.end(); ++it)
492 for (uint32_t i = 0; i < it->second->size(); i++)
496 (*it->second)[i]->addValue((*(*state_timer_data_container_ptr_)[it->first])[i]);
497 (*(*state_timer_data_container_ptr_)[it->first])[i] = 0;
505 std::string getDisplayStringCumulativeAllState()
507 std::string histogram_string =
"";
508 for (
auto it = timer_histogram_map_.begin(); it != timer_histogram_map_.end(); ++it)
510 for (uint32_t i = 0; i < it->second->size(); i++)
512 histogram_string += (*it->second)[i]->getDisplayStringCumulative();
515 return histogram_string;
521 std::string getDisplayStringCumulativeOneState(uint32_t state_set_hash_code, uint32_t state_index)
523 std::string histogram_string =
"";
524 auto it = timer_histogram_map_.find(state_set_hash_code);
526 "Can not find state enum class in histogram map.");
527 histogram_string = (*it->second)[state_index]->getDisplayStringCumulative();
528 return histogram_string;
534 std::unordered_map<uint32_t, std::shared_ptr<std::vector<std::shared_ptr<sparta::Histogram>>>>
535 timer_histogram_map_;
537 StateTimerDataContainerPtr state_timer_data_container_ptr_;
545 template<
class ArgsHeadT,
class... ArgsTailT>
546 void addStateSet_(ArgsHeadT state_sets_head, ArgsTailT... state_sets_tail)
548 uint32_t state_set_hash_code =
typeid(state_sets_head).hash_code();
549 uint32_t num_state =
static_cast<uint32_t
>(state_sets_head);
550 sparta_assert(state_set_info_map_ptr_->find(state_set_hash_code) == state_set_info_map_ptr_->end(),
551 "Same enum class exists.");
552 state_set_info_map_ptr_->insert(std::unordered_map<uint32_t,uint32_t>::value_type
553 (state_set_hash_code, num_state));
555 state_set_name_map_.insert(std::unordered_map<uint32_t, std::string>::value_type
556 (state_set_hash_code,
typeid(state_sets_head).name()));
558 addStateSet_(state_sets_tail...);
570 void updateStateHistogram_(StateTimer::TimerId timer_id,
bool is_release_timer)
573 state_timer_histogram_ptr_->updateHistogram();
575 if (is_release_timer)
577 state_timer_pool_ptr_->releaseTimer(timer_id);
585 StateTimerDataContainerPtr getStateTimerInfoContainer_()
587 return state_timer_data_container_ptr_;
591 StateTimerDataContainerPtr state_timer_data_container_ptr_;
593 StateTimer::StateSetInfo state_set_info_map_ptr_;
595 std::unique_ptr<StateTimerPool> state_timer_pool_ptr_;
597 std::unique_ptr<StateTimerHistogram> state_timer_histogram_ptr_;
599 std::unordered_map<uint32_t, std::string> state_set_name_map_;