Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/idiom/iroot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions src/idiom/iroot.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ class iRoot {
IdiomType idiom() { return proto_->idiom(); }

void AddEvent(iRootEvent *event) { events_.push_back(event); }

void AddCountPair(std::pair<int, int>* 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();
Expand Down
3 changes: 3 additions & 0 deletions src/idiom/iroot.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
120 changes: 120 additions & 0 deletions src/idiom/predictor_new.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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 <AccSum*, AccSum*>* acc_sum_pair = new std::pair <AccSum*, AccSum*> (src, dst);

std::pair <int, int>* count_pair = new std::pair <int, int> (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);
Expand Down Expand Up @@ -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<int, int>* PredictorNew::searchForAccSumPair(AccSum* src, AccSum* dst) {

std::map <std::pair<AccSum*, AccSum*>*, std::pair<int, int>*>::iterator iter;

for (iter = iroot_inst_count_map.begin(); iter != iroot_inst_count_map.end(); ++iter) {

std::pair<AccSum*, AccSum*>* 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();
Expand All @@ -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<int, int>* 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);
Expand All @@ -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());
Expand Down
12 changes: 12 additions & 0 deletions src/idiom/predictor_new.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

#include <map>
#include <set>
#include <list>
#include <tr1/unordered_map>
#include <stack>

#include "core/basictypes.h"
#include "core/analyzer.h"
Expand Down Expand Up @@ -160,8 +162,13 @@ class PredictorNew : public Analyzer {
Inst *inst;
FLockSet fls;
TimeInfo tinfo;

};

public :
std::map <std::pair<AccSum*, AccSum*>*, std::pair<int, int>*> iroot_inst_count_map ;

protected :
// the dynamic access
class DynAcc {
public:
Expand Down Expand Up @@ -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;
};
Expand Down Expand Up @@ -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<int, int>* searchForAccSumPair(AccSum* src, AccSum* dst);

// common databases
Mutex *internal_lock_;
StaticInfo *sinfo_;
Expand Down
50 changes: 45 additions & 5 deletions src/idiom/scheduler_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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)) {
Expand All @@ -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();
Expand Down
4 changes: 4 additions & 0 deletions src/idiom/scheduler_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class Idiom1SchedStatus {
size_t size_[2];
DelaySet delay_set_;

// pankit
map <thread_id_t, long> num_mem_acc;

friend class SchedulerCommon;

DISALLOW_COPY_CONSTRUCTORS(Idiom1SchedStatus);
Expand Down Expand Up @@ -681,6 +684,7 @@ class SchedulerCommon : public ExecutionControl {
std::map<thread_id_t, int> priority_map_;
std::map<thread_id_t, int> ori_priority_map_;
std::map<thread_id_t, OS_THREAD_ID> thd_id_os_tid_map_;

bool volatile start_schedule_; // start scheduling when 2 threads are started
bool volatile test_success_;

Expand Down