From 0d5a84999eccb9036061d388b2c125fcca9e461e Mon Sep 17 00:00:00 2001 From: pankit Date: Fri, 25 Jan 2013 23:25:19 -0500 Subject: [PATCH] Code Chanes for Dynamic Instruction count --- src/idiom/iroot.cc | 6 ++ src/idiom/iroot.h | 12 ++++ src/idiom/iroot.proto | 3 + src/idiom/predictor_new.cc | 120 +++++++++++++++++++++++++++++++++ src/idiom/predictor_new.h | 12 ++++ src/idiom/scheduler_common.cpp | 50 ++++++++++++-- src/idiom/scheduler_common.hpp | 4 ++ 7 files changed, 202 insertions(+), 5 deletions(-) diff --git a/src/idiom/iroot.cc b/src/idiom/iroot.cc index d661ed49..ebcd3092 100644 --- a/src/idiom/iroot.cc +++ b/src/idiom/iroot.cc @@ -198,12 +198,18 @@ iRoot *iRootDB::CreateiRoot(IdiomType idiom, iRootEventVec *events, iroot_id_t iroot_id = GetNextiRootID(); iroot_proto->set_id(iroot_id); iroot_proto->set_idiom(idiom); + //pankit fix + iroot_proto->set_src_count(0); + iroot_proto->set_dst_count(0); + iroot_proto->set_count_pair_bool(0); + iRoot *iroot = new iRoot(iroot_proto); for (size_t i = 0; i < events->size(); i++) { iRootEvent *event = (*events)[i]; iroot_proto->add_event_id(event->id()); iroot->AddEvent(event); } + iroot_map_[iroot_id] = iroot; size_t hash_val = HashiRoot(idiom, events); iroot_index_[hash_val].push_back(iroot); // update index diff --git a/src/idiom/iroot.h b/src/idiom/iroot.h index c622c890..838e117e 100644 --- a/src/idiom/iroot.h +++ b/src/idiom/iroot.h @@ -81,6 +81,18 @@ class iRoot { IdiomType idiom() { return proto_->idiom(); } void AddEvent(iRootEvent *event) { events_.push_back(event); } + + void AddCountPair(std::pair* counts) { + + proto_->set_count_pair_bool(1); + proto_->set_src_count(counts->first); + proto_->set_dst_count(counts->second); + } + + uint32 getDstCount() { return proto_->src_count(); } + uint32 getSrcCount() { return proto_->dst_count(); } + uint32 getCountPairBool() { return proto_->count_pair_bool(); } + iRootEvent *GetEvent(int index) { return events_[index]; } bool HasMem(); bool HasSync(); diff --git a/src/idiom/iroot.proto b/src/idiom/iroot.proto index 751061fb..aa0a4c10 100644 --- a/src/idiom/iroot.proto +++ b/src/idiom/iroot.proto @@ -27,6 +27,9 @@ message iRootProto { required uint32 id = 1; required IdiomType idiom = 2; repeated uint32 event_id = 3; + required uint32 count_pair_bool = 4; + required uint32 src_count = 5; + required uint32 dst_count = 6; } message iRootDBProto { diff --git a/src/idiom/predictor_new.cc b/src/idiom/predictor_new.cc index 482f09f1..0e220951 100644 --- a/src/idiom/predictor_new.cc +++ b/src/idiom/predictor_new.cc @@ -188,6 +188,7 @@ void PredictorNew::SignalReceived(thread_id_t curr_thd_id, void PredictorNew::ThreadStart(thread_id_t curr_thd_id, thread_id_t parent_thd_id) { + // create thread local vector clock and lockset VectorClock *curr_vc = new VectorClock; LockSet *curr_ls = new LockSet; @@ -218,6 +219,7 @@ void PredictorNew::BeforeMemRead(thread_id_t curr_thd_id, Inst *inst, address_t addr, size_t size) { + // XXX: this function needs to be implemented as fast as possible ScopedLock locker(internal_lock_); if (FilterAccess(addr)) @@ -729,6 +731,22 @@ bool PredictorNew::ExistAccSumPair(AccSum *src, AccSum *dst) { } void PredictorNew::AddAccSumPair(AccSum *src, AccSum *dst) { + + // only add the count pair for mem accsum + if ((src->type == IROOT_EVENT_MEM_READ || src->type == IROOT_EVENT_MEM_WRITE) && + (dst->type == IROOT_EVENT_MEM_READ || dst->type == IROOT_EVENT_MEM_WRITE)) { + + int src_count = getNumAcc(src); + + int dst_count = getNumAcc(dst); + + std::pair * acc_sum_pair = new std::pair (src, dst); + + std::pair * count_pair = new std::pair (src_count, dst_count); + + iroot_inst_count_map[acc_sum_pair] = count_pair; + } + // add src->dst (precondition: no duplication) acc_sum_succ_index_[src].push_back(dst); acc_sum_pred_index_[dst].push_back(src); @@ -937,6 +955,75 @@ PredictorNew::BarrierMeta *PredictorNew::GetBarrierMeta(address_t iaddr) { } } +// return the number of mem accesses to the same memory before current access +int PredictorNew::getNumAcc(AccSum* acc_sum) { + + int count = 0; + + AccSum::TimeInfoEntry &tinfo_entry = acc_sum->tinfo.back(); + + ThdClkInfo thd_clk_info = tinfo_entry.second; + + timestamp_t thd_start = thd_clk_info.start; + + AccHisto *acc_histo = acc_sum->meta->acc_histo; + + thread_id_t thd_id = acc_sum->thd_id; + + for (AccHisto::AccSumTable::iterator tit = acc_histo->acc_sum_table.begin(); + tit != acc_histo->acc_sum_table.end(); ++tit) { + + //check this thread's access history + if (tit->first == thd_id) { + + for (AccSum::Vec::iterator vit = tit->second.begin(); + vit != tit->second.end(); ++vit) { + + AccSum *rmt_acc_sum = *vit; + + bool same = false; + + for (AccSum::TimeInfo::reverse_iterator it = rmt_acc_sum->tinfo.rbegin(); + it != rmt_acc_sum->tinfo.rend(); ++it) { + + AccSum::TimeInfoEntry &entry = *it; + + ThdClkInfo thd_clk_info = entry.second; + + timestamp_t rmt_thd_start = thd_clk_info.start; + + if (rmt_thd_start < thd_start && !same) { + + count++; + } + } + } + } + } + + return count; +} + +// used for number of accesses, returns the number of memory accesses before this in both src and dst +std::pair* PredictorNew::searchForAccSumPair(AccSum* src, AccSum* dst) { + + std::map *, std::pair*>::iterator iter; + + for (iter = iroot_inst_count_map.begin(); iter != iroot_inst_count_map.end(); ++iter) { + + std::pair* acc_sum_pair = iter->first; + + if ((src == acc_sum_pair->first) && (dst == acc_sum_pair->second) && + (src->thd_id == acc_sum_pair->first->thd_id) && + (dst->thd_id == acc_sum_pair->second->thd_id)) { + + return iter->second; + } + } + + return NULL; +} + void PredictorNew::PredictiRoot() { // predict idiom1 iroots according to access summary pairs for (AccSum::PairIndex::iterator iit = acc_sum_succ_index_.begin(); @@ -949,6 +1036,38 @@ void PredictorNew::PredictiRoot() { iRootEvent *e0 = iroot_db_->GetiRootEvent(src->inst, src->type, false); iRootEvent *e1 = iroot_db_->GetiRootEvent(dst->inst, dst->type, false); iRoot *iroot = iroot_db_->GetiRoot(IDIOM_1, false, e0, e1); + if ((src->type == IROOT_EVENT_MEM_READ || src->type == IROOT_EVENT_MEM_WRITE) && + (dst->type == IROOT_EVENT_MEM_READ || dst->type == IROOT_EVENT_MEM_WRITE)) { + + std::pair* count_pair = searchForAccSumPair(src, dst); + + if (count_pair) { + + int src_count = count_pair->first; + + int dst_count = count_pair->second; + + int old_src_count = iroot->getSrcCount(); + + int old_dst_count = iroot->getDstCount(); + + // we need the minimum number of mem access before. Therfore, take the min of all the mem acc counts + if (iroot->getCountPairBool()) { + + if (old_src_count < src_count) { + + count_pair->first = old_src_count; + } + + if (old_dst_count < dst_count) { + + count_pair->second = old_dst_count; + } + } + iroot->AddCountPair(count_pair); + } + } + memo_->Predicted(iroot, false); if (CheckAsync(src) || CheckAsync(dst)) { memo_->SetAsync(iroot, false); @@ -966,6 +1085,7 @@ PredictorNew::AccSum *PredictorNew::ProcessAccSumUpdate(DynAcc *dyn_acc) { // check whether a matching access summary can be found AccSum *curr_acc_sum = MatchAccSum(dyn_acc); if (curr_acc_sum) { + // check whether a new vector clock value has been observed // for this access summary. only need to check the last vc. DEBUG_ASSERT(!curr_acc_sum->tinfo.empty()); diff --git a/src/idiom/predictor_new.h b/src/idiom/predictor_new.h index d1772877..d112ceb1 100644 --- a/src/idiom/predictor_new.h +++ b/src/idiom/predictor_new.h @@ -21,7 +21,9 @@ #include #include +#include #include +#include #include "core/basictypes.h" #include "core/analyzer.h" @@ -160,8 +162,13 @@ class PredictorNew : public Analyzer { Inst *inst; FLockSet fls; TimeInfo tinfo; + }; + public : + std::map *, std::pair*> iroot_inst_count_map ; + + protected : // the dynamic access class DynAcc { public: @@ -259,6 +266,7 @@ class PredictorNew : public Analyzer { explicit Meta(Type t) : type(t) { acc_histo = new AccHisto; } ~Meta() { if (acc_histo) delete acc_histo; } + Type type; AccHisto *acc_histo; }; @@ -398,6 +406,10 @@ class PredictorNew : public Analyzer { void ProcessPreBarrier(thread_id_t curr_thd_id, BarrierMeta *meta); void ProcessPostBarrier(thread_id_t curr_thd_id, BarrierMeta *meta); + int getNumAcc(AccSum*); + + std::pair* searchForAccSumPair(AccSum* src, AccSum* dst); + // common databases Mutex *internal_lock_; StaticInfo *sinfo_; diff --git a/src/idiom/scheduler_common.cpp b/src/idiom/scheduler_common.cpp index 095a3d0a..f924839e 100644 --- a/src/idiom/scheduler_common.cpp +++ b/src/idiom/scheduler_common.cpp @@ -1551,6 +1551,16 @@ void SchedulerCommon::Idiom1BeforeEvent0(address_t addr, size_t size) { DEBUG_STAT_INC("event0", 1); + // pankit fix : increment the count for curr_thd + if (s->num_mem_acc.find(curr_thd_id) == s->num_mem_acc.end()) { + + s->num_mem_acc[curr_thd_id] = 1; + + } else { + + s->num_mem_acc[curr_thd_id] = s->num_mem_acc.find(curr_thd_id)->second + 1; + } + while (true) { // control variables bool restart = false; @@ -1964,6 +1974,17 @@ void SchedulerCommon::Idiom1WatchAccess(address_t addr, size_t size) { DEBUG_ASSERT(GetPriority(curr_thd_id) == LowerPriority()); if (OVERLAP(addr, size, s->addr_[0], s->size_[0])) { // cannot be delayed any more + + // pankit fix : increment the count for the curr_thd + if (s->num_mem_acc.find(curr_thd_id) == s->num_mem_acc.end()) { + + s->num_mem_acc[curr_thd_id] = 1; + + } else { + + s->num_mem_acc[curr_thd_id] = s->num_mem_acc.find(curr_thd_id)->second + 1; + } + if (Idiom1CheckGiveup(2)) { DEBUG_FMT_PRINT_SAFE("[T%lx] watch access give up\n", curr_thd_id); DelaySet copy; @@ -1982,6 +2003,16 @@ void SchedulerCommon::Idiom1WatchAccess(address_t addr, size_t size) { } } else { if (OVERLAP(addr, size, s->addr_[0], s->size_[0])) { + // pankit fix : increment the count for the curr_thd + if (s->num_mem_acc.find(curr_thd_id) == s->num_mem_acc.end()) { + + s->num_mem_acc[curr_thd_id] = 1; + + } else { + + s->num_mem_acc[curr_thd_id] = s->num_mem_acc.find(curr_thd_id)->second + 1; + } + if (GetPriority(curr_thd_id) == LowerPriority()) { // cannot be delayed any more if (Idiom1CheckGiveup(2)) { @@ -1999,11 +2030,20 @@ void SchedulerCommon::Idiom1WatchAccess(address_t addr, size_t size) { UnlockSchedStatus(); restart = true; } - } else { - s->delay_set_.insert(curr_thd_id); - UnlockSchedStatus(); - SetPriorityLow(curr_thd_id); - restart = true; + + // pankit fix : if the count is satisfied then only give up, else increment go ahead with high priority + } else { + + if (curr_iroot_->getCountPairBool() && s->num_mem_acc.find(curr_thd_id) != s->num_mem_acc.end() && + s->num_mem_acc.find(curr_thd_id)->second != curr_iroot_->getDstCount()) { + UnlockSchedStatus(); + SetPriorityHigh(curr_thd_id); + } else { + s->delay_set_.insert(curr_thd_id); + UnlockSchedStatus(); + SetPriorityLow(curr_thd_id); + restart = true; + } } } else { UnlockSchedStatus(); diff --git a/src/idiom/scheduler_common.hpp b/src/idiom/scheduler_common.hpp index 7611245b..70c5bf2d 100644 --- a/src/idiom/scheduler_common.hpp +++ b/src/idiom/scheduler_common.hpp @@ -77,6 +77,9 @@ class Idiom1SchedStatus { size_t size_[2]; DelaySet delay_set_; + // pankit + map num_mem_acc; + friend class SchedulerCommon; DISALLOW_COPY_CONSTRUCTORS(Idiom1SchedStatus); @@ -681,6 +684,7 @@ class SchedulerCommon : public ExecutionControl { std::map priority_map_; std::map ori_priority_map_; std::map thd_id_os_tid_map_; + bool volatile start_schedule_; // start scheduling when 2 threads are started bool volatile test_success_;