#include "interface.h" // Do NOT edit interface .h #include "sample_prefetcher.h" const int mshr_size = 128; const int segment_size = 1000000; const double useful_thresh_high1 = 0.45; const double useful_thresh_low1 = 0.45; const double late_thresh1 = 0.07; const double poll_thresh1 = 0.01; const int queue_thresh1 = 35; const double bandwidth_thresh1 = 0.07; const int pref_deg1 = 2; const int pref_dist1 = 16; const double useful_thresh_high2 = 0.45; const double useful_thresh_low2 = 0.45; const double late_thresh2 = 0.07; const double poll_thresh2 = 0.01; const int queue_thresh2 = 10; const int pref_deg2 = 2; const int pref_dist2 = 16; const int pfilter_size_lg = 0; const double bandwidth_thresh2 = 0.07; /* #define MSHR_SIZE mshr_size #define PFILTER_SIZE_LG (pfilter_size_lg) #define SEGMENT_SIZE (segment_size) #define USEFUL_THRESH_HIGH1 (useful_thresh_high1) #define USEFUL_THRESH_LOW1 (useful_thresh_low1) #define LATE_THRESH1 (late_thresh1) #define POLL_THRESH1 (poll_thresh1) #define QUEUE_THRESH1 (queue_thresh1) #define PREF_DEGREE1 (pref_degree1) #define PREF_DISTANCE1 (pref_distance1) #define USEFUL_THRESH_HIGH2 (useful_thresh_high2) #define USEFUL_THRESH_LOW2 (useful_thresh_low2) #define LATE_THRESH2 (late_thresh2) #define POLL_THRESH2 (poll_thresh2) #define QUEUE_THRESH2 (queue_thresh2) #define PREF_DEGREE2 (pref_degree2) #define PREF_DISTANCE2 (pref_distance2) */ COUNTER cycleNum; struct MSHR_t { CacheAddr_t insn_addr; UINT32 cache_level; bool valid_bit; bool prefetch_bit0; bool prefetch_bit1; }; // Pollution Filter // Increment on prefetch lines brought into set, decrement on demand miss to set struct PFilter_t { int set_count; }; class Prefetch_Evaluator { public: Prefetch_Evaluator(){ total_prefs1 = 0; useful_prefs1 = 0; total_demand_misses1 = 0; pref_demand_misses1 = 0; late_prefs1 = 0; total_prefs2 = 0; total_prefs2_from1 = 0; useful_prefs2 = 0; total_demand_misses2 = 0; pref_demand_misses2 = 0; late_prefs2 = 0; //Next three just for analyzing data queuelim_l1count = 0; queuelim_l2count = 0; queuelim_l1numcycles = 0; queuelim_l2numcycles = 0; changeaggr_count = 0; pref_distance1 = pref_dist1; pref_distance2 = pref_dist2; pref_degree1 = pref_deg1; pref_degree2 = pref_deg2; total_segment = 0; total_segment_l2 = 0; MSHR_list = new MSHR_t[mshr_size]; for(int i = 0;i < mshr_size;i++) { MSHR_list[i].valid_bit = false; } int PFilter_Size = 1 << pfilter_size_lg; PFilt_table = new PFilter_t[PFilter_Size]; for(int i = 0;i < PFilter_Size;i++) { PFilt_table[i].set_count = 0; } }; // For a given cache level, this Returns -1 if element is not in MSHR, 0 if demand // request, 1 if prefetch request and 2 if present in MSHR at different level int LookupMSHR(CacheAddr_t lookup_addr, bool demand_request, UINT32 cache_level); int UpdateMSHRS(int *l1_outstanding, int *l2_outstanding); //Always call LookupMSHR before calling the next two functions // Insert assuming that the address is not in the set of valid MSHRs bool InsertMSHR(CacheAddr_t insn_addr, UINT32 cache_level, bool is_prefetch); // Used to modify the cache level of an existing entry bool ModifyLevelMSHR(CacheAddr_t insn_addr, UINT32 cache_level, bool is_prefetch); //void IssuePrefetches //(COUNTER cycle, PrefetchData_t *L1Data, PrefetchData_t *L2Data ); COUNTER total_prefs1, useful_prefs1, total_demand_misses1, pref_demand_misses1, late_prefs1; COUNTER total_prefs2, useful_prefs2, total_demand_misses2, pref_demand_misses2, late_prefs2; COUNTER total_prefs2_from1; // L2 prefetches due to L1 misses int pref_degree1, pref_degree2; // The number of prefetches issued on a miss int pref_distance1, pref_distance2; // The distance from the miss that prefetches are issued int total_segment,total_segment_l2; // The total number of memory instructions in this segment int queuelim_l1count,queuelim_l2count; int queuelim_l1numcycles,queuelim_l2numcycles; int changeaggr_count; MSHR_t *MSHR_list; PFilter_t *PFilt_table; // Bloom Filter }; Prefetch_Evaluator *pref_evaluator; SamplePrefetcher *pref1; // This is the L1 prefetcher SamplePrefetcher *pref2; // This is the L2 prefetcher // Assumes that element is not already in MSHR, always call LookupMSHR first bool Prefetch_Evaluator::InsertMSHR (CacheAddr_t insn_addr, UINT32 cache_level, bool is_prefetch) { int i = 0; while(i < mshr_size && MSHR_list[i].valid_bit == true) i++; if(i == mshr_size) return false; MSHR_list[i].insn_addr = (insn_addr >> 6) << 6; //fprintf(out,"Now inserting cache address %x into MSHR with prefetch bit %d\n", // (unsigned int)MSHR_list[i].insn_addr,(int)is_prefetch); MSHR_list[i].cache_level = cache_level; if(cache_level == 0) { MSHR_list[i].prefetch_bit0 = is_prefetch; MSHR_list[i].prefetch_bit1 = 0; } else { MSHR_list[i].prefetch_bit1 = is_prefetch; MSHR_list[i].prefetch_bit0 = 0; } MSHR_list[i].valid_bit = true; return true; } // Assumes that element is already in MSHR, always call LookupMSHR first // Used to modify the cache level of an existing entry bool Prefetch_Evaluator::ModifyLevelMSHR (CacheAddr_t insn_addr, UINT32 cache_level, bool is_prefetch) { insn_addr = (insn_addr >> 6) << 6; for(int i = 0;i < mshr_size;i++) { if(MSHR_list[i].insn_addr == insn_addr) { //fprintf(out,"Modifying the MSHR level of cache address %x to %d\n", // (unsigned int)insn_addr,cache_level); // If previous cache level is 0 and this // is a prefetch request (it will be for level 1) if(is_prefetch && MSHR_list[i].cache_level == 0) { MSHR_list[i].prefetch_bit1 = true; } else if(is_prefetch && MSHR_list[i].cache_level == 1) { MSHR_list[i].prefetch_bit0 = true; } MSHR_list[i].cache_level = cache_level; return true; } } return false; } int Prefetch_Evaluator::UpdateMSHRS(int *l1_outstanding, int *l2_outstanding) { int num_new_lines = 0; *l1_outstanding = 0; *l2_outstanding = 0; for(int i = 0;i < mshr_size;i++) { MSHR_t *MSHR_elt = &MSHR_list[i]; if(MSHR_elt->valid_bit == false) continue; // There is a request for both L1 and L2 if(MSHR_elt->cache_level == 100) { int prefetch_bit1; int prefetch_bit2; prefetch_bit1 = GetPrefetchBit(0,MSHR_elt->insn_addr); prefetch_bit2 = GetPrefetchBit(1,MSHR_elt->insn_addr); //Both requests are still outstanding if(prefetch_bit1 == -1 && prefetch_bit2 == -1) { *l1_outstanding = *l1_outstanding + 1; *l2_outstanding = *l2_outstanding + 1; } // The L1 request is still outstanding but L2 is not else if(prefetch_bit1 == -1) { MSHR_elt->cache_level = 0; //This will ensure that a late/useful L2 prefetch is not double counted as useful later if(prefetch_bit2 == 1 && MSHR_elt->prefetch_bit1 == 0) UnSetPrefetchBit(1,MSHR_elt->insn_addr); *l1_outstanding = *l1_outstanding + 1; num_new_lines++; } // The L2 request is still outstanding but L1 is not else if(prefetch_bit2 == -1) { MSHR_elt->cache_level = 1; if(prefetch_bit1 == 1 && MSHR_elt->prefetch_bit0 == 0) UnSetPrefetchBit(0,MSHR_elt->insn_addr); *l2_outstanding = *l2_outstanding + 1; num_new_lines++; } //Both requests are completed else if(prefetch_bit1 != -1 && prefetch_bit2 != -1) { if(prefetch_bit2 == 1 && MSHR_elt->prefetch_bit1 == 0) UnSetPrefetchBit(1,MSHR_elt->insn_addr); if(prefetch_bit1 == 1 && MSHR_elt->prefetch_bit0 == 0) UnSetPrefetchBit(0,MSHR_elt->insn_addr); MSHR_elt->valid_bit = false; num_new_lines++; } } else { int prefetch_bit = GetPrefetchBit(MSHR_elt->cache_level,MSHR_elt->insn_addr); // Data is now in the cache and hence no longer in flight or in queue if(prefetch_bit != -1) { num_new_lines++; if(prefetch_bit == 1) { if(MSHR_elt->cache_level == 0 && MSHR_elt->prefetch_bit0 == 0) { UnSetPrefetchBit(0,MSHR_elt->insn_addr); } else if(MSHR_elt->cache_level == 1 && MSHR_elt->prefetch_bit1 == 0) { UnSetPrefetchBit(1,MSHR_elt->insn_addr); } } MSHR_elt->valid_bit = false; } else { MSHR_elt->cache_level == 0 ? *l1_outstanding = *l1_outstanding + 1 : *l2_outstanding = *l2_outstanding + 1; } } } return num_new_lines; } // For a given cache level, this Returns -1 if element is not in MSHR, 0 if demand // request, 1 if prefetch request and 2 if present in MSHR at different cache level int Prefetch_Evaluator::LookupMSHR (CacheAddr_t lookup_addr, bool demand_request, UINT32 cache_level) { lookup_addr = (lookup_addr >> 6) << 6; for(int i = 0;i < mshr_size;i++) { MSHR_t *MSHR_elt = &MSHR_list[i]; if(MSHR_elt->valid_bit && MSHR_elt->insn_addr == lookup_addr) { bool cache_level_ok = MSHR_elt->cache_level == 100 || MSHR_elt->cache_level == cache_level; // If lookup is done for demand request and prefetch bit is set, change bit // Do this only if the lookup is for the same cache level as the entry if(cache_level_ok) { if(cache_level == 0) { int temp = MSHR_elt->prefetch_bit0 == false ? 0 : 1; // If true, set to false since demand request. If false, it will be unchanged if(demand_request) { MSHR_elt->prefetch_bit0 = false; } return temp; } else if (cache_level == 1) { int temp = MSHR_elt->prefetch_bit1 == false ? 0 : 1; if(demand_request) { MSHR_elt->prefetch_bit1 = false; } return temp; } } else // If address is in MSHR but at a different level than the lookup { return 2; } } } return -1; } // // Function to initialize the prefetchers. DO NOT change the prototype of this // function. You can change the body of the function by calling your necessary // initialization functions. // void InitPrefetchers() // DO NOT CHANGE THE PROTOTYPE { // INSERT YOUR CHANGES IN HERE pref1 = new SamplePrefetcher(); pref2 = new SamplePrefetcher(); pref_evaluator = new Prefetch_Evaluator(); } // // Function that is called every cycle to issue prefetches should the // prefetcher want to. The arguments to the function are the current cycle, // the demand requests to L1 and L2 cache. Again, DO NOT change the prototype of this // function. You can change the body of the function by calling your necessary // routines to invoke your prefetcher. // // DO NOT CHANGE THE PROTOTYPE void IssuePrefetches( COUNTER cycle, PrefetchData_t *L1Data, PrefetchData_t * L2Data ) { // INSERT YOUR CHANGES IN HERE MemLogEntry *entry; CacheAddr_t addr; int l1_outstanding, l2_outstanding; cycleNum = cycle; pref_evaluator->UpdateMSHRS(&l1_outstanding, &l2_outstanding); pref_evaluator->total_segment++; if(l1_outstanding > queue_thresh1 - 5) pref_evaluator->queuelim_l1numcycles++; if(l2_outstanding > queue_thresh2 - 3) pref_evaluator->queuelim_l2numcycles++; // Issue L1 prefetches for(int i = 0; i < 4; i++) { PrefetchData_t* const pd = &L1Data[i]; if(pd->LastRequestCycle != cycle) continue; //DEBUGGING if(pd->hit) { //fprintf(out,"L1 hit in cycle %d for insn address %x and data address %x\n", // (unsigned int)cycle,(unsigned int)pd->LastRequestAddr,(unsigned int)pd->DataAddr); } entry = pref1->AccessEntry(0,pd->LastRequestAddr,pd->DataAddr); if(pd->hit && GetPrefetchBit(0,pd->DataAddr) == 1) { //fprintf(out,"A useful L1 prefetch detected for line %x address %x in cycle %d\n", // (unsigned int)((pd->DataAddr >> 6) << 6),(unsigned int)pd->DataAddr,(unsigned int)cycle); pref_evaluator->useful_prefs1++; UnSetPrefetchBit(0,pd->DataAddr); //Prefetch if a useful prefetch is found if(entry && entry->count >= 2) { if(entry->count == 2) { addr = pd->DataAddr + (pref_evaluator->pref_distance1)*entry->stride; } else { addr = pd->DataAddr + (pref_evaluator->pref_distance1 + pref_evaluator->pref_degree1 - 1)*entry->stride; } if(l1_outstanding < queue_thresh1) { bool pref_issued_flag = false; // Issue only one prefetch at most for(int j = 0; j < pref_evaluator->pref_degree1; j++) { if(pref_issued_flag) continue; int lookupValB = pref_evaluator->LookupMSHR(addr,false,0); if(GetPrefetchBit(0,addr) == -1 && (lookupValB == -1 || lookupValB == 2)) { if(lookupValB == -1) pref_evaluator->InsertMSHR(addr,0,true); else pref_evaluator->ModifyLevelMSHR(addr,100,true); IssueL1Prefetch(cycle,addr); pref_issued_flag = true; pref_evaluator->total_prefs1++; } addr += entry->stride; } } else { pref_evaluator->queuelim_l1count++; } } else // Do sequential prefetching if previous line is present in cache { CacheAddr_t line_addr = ((pd->DataAddr >> 6) << 6); if(GetPrefetchBit(0,line_addr - 64) != -1) { addr = line_addr + 64; //fprintf(out,"Doing L1 sequential prefetching since line addr %x is prefetched\n", // (unsigned)line_addr); bool pref_issued_flag = false; for(int i = 0;i < pref_evaluator->pref_degree1;i++) { if(pref_issued_flag) continue; int lookupValB = pref_evaluator->LookupMSHR(addr,false,0); if(GetPrefetchBit(0,addr) == -1 && (lookupValB == -1 || lookupValB == 2)) { if(lookupValB == -1) pref_evaluator->InsertMSHR(addr,0,true); else pref_evaluator->ModifyLevelMSHR(addr,100,true); pref_issued_flag = true; //fprintf(out,"Issuing sequential prefetch for addr %x\n",(unsigned int)addr); IssueL1Prefetch(cycle,addr); pref_evaluator->total_prefs1++; } addr = addr + 64; } } } } if(pd->hit == 0) { //DEBUGGING //fprintf(out,"L1 miss in cycle %d for insn address %x and data address %x with line address %x\n", // (unsigned int)cycle,(unsigned int)pd->LastRequestAddr,(unsigned int)pd->DataAddr, // (unsigned int)((pd->DataAddr >> 6) << 6)); //pref_evaluator->total_segment++; pref_evaluator->total_demand_misses1++; // If this address is being prefetched and in MSHR, late prefetch if(pref_evaluator->LookupMSHR(pd->DataAddr,true,0) == 1) { //fprintf(out,"A late/useful L1 prefetch detected in cycle %d for line %x address %x\n", // (unsigned int)cycle,(unsigned int)((pd->DataAddr >> 6) << 6),(unsigned int)pd->DataAddr); pref_evaluator->late_prefs1++; pref_evaluator->useful_prefs1++; } int lookupVal = pref_evaluator->LookupMSHR(pd->DataAddr,false,0); if(lookupVal == -1 || lookupVal == 2) { if(lookupVal == -1) pref_evaluator->InsertMSHR(pd->DataAddr,0,false); // This request is inflight from both L1 and L2 // Hence it is a level 100 request else pref_evaluator->ModifyLevelMSHR(pd->DataAddr,100,false); } if(entry && entry->count >= 2) { //The first time this is being prefetched if(entry->count == 2) { addr = pd->DataAddr + (pref_evaluator->pref_distance1)*entry->stride; } else //After the first set of prefetches, go further ahead { addr = pd->DataAddr + (pref_evaluator->pref_distance1 + pref_evaluator->pref_degree1 - 1)*entry->stride; } if(l1_outstanding < queue_thresh1) { for(int j = 0; j < pref_evaluator->pref_degree1; j++) { int lookupValB = pref_evaluator->LookupMSHR(addr,false,0); // If address is not in cache or at the right level of the MSHR if(GetPrefetchBit(0,addr) == -1 && (lookupValB == -1 || lookupValB == 2)) { if(lookupValB == -1) pref_evaluator->InsertMSHR(addr,0,true); else pref_evaluator->ModifyLevelMSHR(addr,100,true); //fprintf(out,"Issuing L1 prefetch for instruction %x address %x line %x in cycle %d\n", // (unsigned int)pd->LastRequestAddr,(unsigned int)addr, // (unsigned int)((addr >> 6) << 6),(unsigned int)cycle); //fprintf(out,"The stride for this prefetch is %d\n",entry->stride); IssueL1Prefetch(cycle,addr); pref_evaluator->total_prefs1++; } addr += entry->stride; } } else { pref_evaluator->queuelim_l1count++; } } else // Do sequential prefetching if previous line is present in cache { CacheAddr_t line_addr = ((pd->DataAddr >> 6) << 6); if(GetPrefetchBit(0,line_addr - 64) != -1) { addr = line_addr + 64; //fprintf(out,"Doing L1 sequential prefetching since there is a miss to line addr %x\n", // (unsigned)line_addr); for(int i = 0;i < pref_evaluator->pref_degree1;i++) { int lookupValB = pref_evaluator->LookupMSHR(addr,false,0); if(lookupValB == -1) pref_evaluator->InsertMSHR(addr,0,true); else pref_evaluator->ModifyLevelMSHR(addr,100,true); if(GetPrefetchBit(0,addr) == -1 && (lookupValB == -1 || lookupValB == 2)) { //fprintf(out,"Issuing sequential prefetch for addr %x\n",(unsigned int)addr); IssueL1Prefetch(cycle,addr); pref_evaluator->total_prefs1++; } addr = addr + 64; } } } } } PrefetchData_t* const pd2 = L2Data; // Issue L2 prefetches if(cycle != pd2->LastRequestCycle) return; // We do not want L1 prefetch hits cause by L2 misses to be counted as a useful L2 prefetch if(pd2->hit && pd2->LastRequestPrefetch) { UnSetPrefetchBit(1, pd2->DataAddr); //fprintf(out,"L2 hit in cycle %d for insn address %x and data address %x\n", // (unsigned int)cycle,(unsigned int)pd2->LastRequestAddr,(unsigned int)pd2->DataAddr); } //To count L2 prefetches which are caused by L1 prefetch misses, remove comments /* if(pd2->LastRequestPrefetch) { //pref_evaluator->total_prefs2++; pref_evaluator->total_prefs2_from1++; } */ entry = pref2->AccessEntry(0,pd2->LastRequestAddr,pd2->DataAddr); //FOR USEFUL PREFETCHES if(pd2->hit && GetPrefetchBit(1,pd2->DataAddr) == 1) { //fprintf(out,"A useful L2 prefetch detected for address %x line %x\n", // (unsigned int)pd2->DataAddr,(unsigned int)((pd2->DataAddr >> 6) << 6)); pref_evaluator->useful_prefs2++; UnSetPrefetchBit(1,pd2->DataAddr); if(entry && entry->count >= 2) { if(entry->count == 2) { addr = pd2->DataAddr + (pref_evaluator->pref_distance2)*entry->stride; } else //After the first set of prefetches, go further ahead { addr = pd2->DataAddr + (pref_evaluator->pref_distance2 + pref_evaluator->pref_degree2 - 1)*entry->stride; } if(l2_outstanding < queue_thresh2) { bool pref_issued_flag = false; // Issue only one prefetch at most for(int j = 0; j < pref_evaluator->pref_degree2; j++) { if(pref_issued_flag) continue; int lookupValB = pref_evaluator->LookupMSHR(addr,false,1); if(GetPrefetchBit(1,addr) == -1 && (lookupValB == -1 || lookupValB == 2)) { if(lookupValB == -1) pref_evaluator->InsertMSHR(addr,1,true); else pref_evaluator->ModifyLevelMSHR(addr,100,true); IssueL2Prefetch(cycle,addr); pref_evaluator->total_prefs2++; } addr += entry->stride; } } else { pref_evaluator->queuelim_l2count++; } } else // Do sequential prefetching if previous line is present in cache { CacheAddr_t line_addr = ((pd2->DataAddr >> 6) << 6); if(GetPrefetchBit(1,line_addr - 64) != -1) { addr = line_addr + 64; //fprintf(out,"Doing L2 sequential prefetching since line addr %x is prefetched\n", // (unsigned)line_addr); bool pref_issued_flag = false; for(int i = 0;i < pref_evaluator->pref_degree2;i++) { if(pref_issued_flag) continue; int lookupValB = pref_evaluator->LookupMSHR(addr,false,1); if(lookupValB == -1) pref_evaluator->InsertMSHR(addr,1,true); else pref_evaluator->ModifyLevelMSHR(addr,100,true); if(GetPrefetchBit(1,addr) == -1 && (lookupValB == -1 || lookupValB == 2)) { pref_issued_flag = true; //fprintf(out,"Issuing sequential prefetch for addr %x\n",(unsigned int)addr); IssueL2Prefetch(cycle,addr); pref_evaluator->total_prefs2++; } addr = addr + 64; } } } } if(pd2->hit == 0) { pref_evaluator->total_segment_l2++; pref_evaluator->total_demand_misses2++; //fprintf(out,"L2 miss in cycle %d for insn address %x and data address %x\n", // (unsigned int)cycle,(unsigned int)pd2->LastRequestAddr,(unsigned int)pd2->DataAddr); //If this address is being prefetched and in MSHR, late prefetch if(pref_evaluator->LookupMSHR(pd2->DataAddr,true,1) == 1) { //fprintf(out,"A late/useful L2 prefetch detected in cycle %d line %x for address %x\n", // (unsigned int)cycle,(unsigned int)((pd2->DataAddr >> 6) << 6),(unsigned int)pd2->DataAddr); pref_evaluator->late_prefs2++; pref_evaluator->useful_prefs2++; } int lookupVal = pref_evaluator->LookupMSHR(pd2->DataAddr,false,1); if(lookupVal == -1 || lookupVal == 2) { //To count L2 prefetches that are caused by L1 prefetch misses, change false to pd2->LastRequestPrefetch if(lookupVal == -1) pref_evaluator->InsertMSHR(pd2->DataAddr,1,false); else pref_evaluator->ModifyLevelMSHR(pd2->DataAddr,100,false); } if(entry && entry->count >= 2) { //The first time this is being prefetched if(entry->count == 2) { addr = pd2->DataAddr + (pref_evaluator->pref_distance2)*entry->stride; } else //After the first set of prefetches, go further ahead { addr = pd2->DataAddr + (pref_evaluator->pref_distance2 + pref_evaluator->pref_degree2 - 1)*entry->stride; } if(l2_outstanding < queue_thresh2) { for(int j = 0; j < pref_evaluator->pref_degree2; j++) { int lookupValB = pref_evaluator->LookupMSHR(addr,false,1); if(GetPrefetchBit(1,addr) == -1 && (lookupValB == -1 || lookupValB == 2)) { if(lookupValB == -1) pref_evaluator->InsertMSHR(addr,1,true); else pref_evaluator->ModifyLevelMSHR(addr,100,true); //fprintf(out,"Issuing L2 prefetch for address %x line %x in cycle %d\n", // (unsigned int)addr,(unsigned int)((addr >> 6) << 6),(unsigned int)cycle); IssueL2Prefetch(cycle,addr); pref_evaluator->total_prefs2++; } addr += entry->stride; } } else { pref_evaluator->queuelim_l2count++; } } else // Do sequential prefetching if previous line is present in cache { CacheAddr_t line_addr = ((pd2->DataAddr >> 6) << 6); if(GetPrefetchBit(1,line_addr - 64) != -1) { addr = line_addr + 64; //fprintf(out,"Doing L1 sequential prefetching since there is a miss to line addr %x\n", //(unsigned)line_addr); for(int i = 0;i < pref_evaluator->pref_degree2;i++) { int lookupValB = pref_evaluator->LookupMSHR(addr,false,1); if(GetPrefetchBit(1,addr) == -1 && (lookupValB == -1 || lookupValB == 2)) { if(lookupValB == -1) pref_evaluator->InsertMSHR(addr,1,true); else pref_evaluator->ModifyLevelMSHR(addr,100,true); IssueL2Prefetch(cycle,addr); pref_evaluator->total_prefs2++; //fprintf(out,"Issuing sequential prefetch for addr %x\n",(unsigned int)addr); } addr = addr + 64; } } } } if(pref_evaluator->total_segment >= segment_size) //|| pref_evaluator->total_segment_l2 >= segment_size) { bool acc_high1, acc_medium1, acc_low1, late1, bandw_high1; bool acc_high2, acc_medium2, acc_low2, late2, bandw_high2; acc_high1 = acc_medium1 = acc_low1 = late1 = bandw_high1 = false; acc_high2 = acc_medium2 = acc_low2 = late2 = bandw_high2 = false; double pref_accuracy1 = (double)pref_evaluator->useful_prefs1 /(double)pref_evaluator->total_prefs1; /* fprintf(out,"The number of useful L1 prefetches %d, total prefetches %d accuracy %.4f\n", (unsigned int)pref_evaluator->useful_prefs1, (unsigned int)pref_evaluator->total_prefs1,pref_accuracy1); fprintf(out,"The number of late L1 prefetches %d, useful prefetches %d late percent %.4f\n", (unsigned int)pref_evaluator->late_prefs1,(unsigned int)pref_evaluator->useful_prefs1, (double)pref_evaluator->late_prefs1/(double)pref_evaluator->useful_prefs1); */ if(pref_accuracy1 > useful_thresh_high1) acc_high1 = true; else if(pref_accuracy1 > useful_thresh_low1) acc_medium1 = true; else acc_low1 = true; //fprintf(out,"The value of acc_high1 %d acc_medium1 %d\n",(int)acc_high1,(int)acc_medium1); if(double(pref_evaluator->late_prefs1) /double(pref_evaluator->useful_prefs1) > late_thresh1) late1 = true; if(double(pref_evaluator->queuelim_l1numcycles) /double(pref_evaluator->total_segment) > bandwidth_thresh1) bandw_high1 = true; //if(double(pref_evaluator->pref_demand_misses1)/ // (double)(pref_evaluator->total_demand_misses1) > poll_thresh1) // poll1 = true; //fprintf(out,"The value of the expression being evaluated for more aggressive is %d\n", //(int)((acc_high1 || acc_medium1) && late1)); if((acc_high1 || acc_medium1) && late1 && !bandw_high1) //Become more aggressive { pref_evaluator->changeaggr_count++; if(pref_evaluator->pref_distance1 < 64) { pref_evaluator->pref_distance1 *= 2; } if(pref_evaluator->pref_degree1 < 4 && pref_evaluator->pref_distance1 >= 16) { pref_evaluator->pref_degree1 *= 2; } } else if((acc_high1 || acc_medium1) && !late1) //No change { } else if(!(acc_high1 ||acc_medium1) && late1) //Become less aggressive { pref_evaluator->changeaggr_count++; if(pref_evaluator->pref_distance1 > 4) { pref_evaluator->pref_distance1 /= 2; } if(pref_evaluator->pref_degree1 > 1) { pref_evaluator->pref_degree1 /= 2; } } else if(!(acc_high1 ||acc_medium1) && !late1) // No change { } double pref_accuracy2 = (double)pref_evaluator->useful_prefs2 /(double)pref_evaluator->total_prefs2; //fprintf(out,"The total number of L2 prefetches which resulted from L1 are %d\n", // (unsigned int)pref_evaluator->total_prefs2_from1); if(pref_accuracy2 > useful_thresh_high2) acc_high2 = true; else if(pref_accuracy2 > useful_thresh_low2) acc_medium2 = true; else acc_low2 = true; //fprintf(out,"The value of acc_high2 %d acc_medium2 %d\n",(int)acc_high2,(int)acc_medium2); if(double(pref_evaluator->late_prefs2) /double(pref_evaluator->useful_prefs2) > late_thresh2) late2 = true; //fprintf(out,"The value of late2 %d\n",(int)late2); //if(double(pref_evaluator->pref_demand_misses2)/ // (double)(pref_evaluator->total_demand_misses2) > poll_thresh2) // poll2 = true; if(double(pref_evaluator->queuelim_l2numcycles) /double(pref_evaluator->total_segment) > bandwidth_thresh2) bandw_high2 = true; if((acc_high2 ||acc_medium2) && late2 && !bandw_high2) //Become more aggressive { pref_evaluator->changeaggr_count++; if(pref_evaluator->pref_distance2 < 64) { pref_evaluator->pref_distance2 *= 2; } if(pref_evaluator->pref_degree2 < 4 && pref_evaluator->pref_distance2 >= 16) { pref_evaluator->pref_degree2 *= 2; } } else if((acc_high2 ||acc_medium2) && !late2) //No change { } else if(!(acc_high2 ||acc_medium2) && late2) //Become less aggressive { pref_evaluator->changeaggr_count++; if(pref_evaluator->pref_distance2 > 4) { pref_evaluator->pref_distance2 /= 2; } if(pref_evaluator->pref_degree2 > 1) { pref_evaluator->pref_degree2 /= 2; } } else if(!(acc_high2 ||acc_medium2) && !late2) // No change { } pref_evaluator->total_segment = 0; pref_evaluator->total_segment_l2 = 0; pref_evaluator->useful_prefs1 = 0; pref_evaluator->total_prefs1 = 0; pref_evaluator->total_demand_misses1 = 0; pref_evaluator->pref_demand_misses1 = 0; pref_evaluator->late_prefs1 = 0; pref_evaluator->queuelim_l1count = 0; pref_evaluator->queuelim_l1numcycles = 0; pref_evaluator->useful_prefs2 = 0; pref_evaluator->total_prefs2 = 0; pref_evaluator->total_prefs2_from1 = 0; pref_evaluator->total_demand_misses2 = 0; pref_evaluator->pref_demand_misses2 = 0; pref_evaluator->late_prefs2 = 0; pref_evaluator->queuelim_l2count = 0; pref_evaluator->queuelim_l2numcycles = 0; } }