📄 iq_seg.cc
字号:
.desc("average push-down insts per event") ; pd_inst_rate = seg_queue->pushdown_count[segment_number] / cpu->numCycles; label.str(""); } // Stats for the ready-queue label.str(""); label << n << setw(2) << setfill('0') << segment_number << ":RQ"; ready_list->regFormulas(label.str(), cpu->number_of_threads);}voidsegment_t::collect_inst_stats(){ typedef map<ROBStation *, unsigned> LoadMap; LoadMap *loads = 0; bool collect_rob_stats = false; // Only allocate this if we're going to use it if (segment_number == 0) loads = new LoadMap; for (iq_it_list_iterator i = head(); i.notnull(); i = i.next()) { unsigned thread = (*i)->thread_number(); // // Is this inst on a chain? // for (int j = 0; j < TheISA::MaxInstSrcRegs; ++j) { if ((*i)->idep_info[j].chained) { ++cum_chained[thread]; break; } } // // Only segment zero does the rest of this stuff... // if (segment_number == 0) { // // We only collect the following data if the ready-queue holds // less than two instructions, and the segment has more than 24 // instructions: // // (1) How many instructions are waiting for an issued load? // (2) How many instructions are waiting for each individual // load (fanout)? // (3) How many instructions are waiting for a non-issued inst // (we hope this number is REALLY small) // if ((total_insts > 23) && (ready_list->count() < 3)) { LoadMap::iterator pos; collect_rob_stats = true; // // What kind of inst is _this_ inst waiting for? // bool load_flag = false; bool unissued_flag = false; for (int j = 0; j < TheISA::MaxInstSrcRegs; ++j) { if (!(*i)->idep_ready[j]) { ROBStation *r = (*i)->idep_ptr[j]->rob_producer; DynInst *p = r->inst; // place issued loads into the list if (p->isLoad() && r->issued) { load_flag = true; // Increment the counter for this ROB entry pos = loads->find(r); if (pos == loads->end()) { // entry not in map... // insert it with counter value=1 loads->insert(make_pair(r,1)); } else { // increment the existing counter ++(pos->second); } } else if (!r->issued) { unissued_flag = true; } } } if (load_flag) ++insts_waiting_for_loads; else if (unissued_flag) ++insts_waiting_for_unissued; } // if number of instructions... } // if segment_number is 0 } // for each instruction // // We do this once, and only if the criteria above have been met // if (collect_rob_stats) { LoadMap::iterator pos = loads->begin(); for (; pos != loads->end(); ++pos) ++insts_fanout_loads; ++cycles_low_ready; } if (segment_number == 0) delete loads;}voidsegment_t::tick_stats(){ // // Do every-cycle stuff // // Statistics for (int i = 0; i < number_of_threads; ++i) cum_insts[i] += insts[i]; if (free_slots() == 0) ++segment_full; else if (count() == 0) ++segment_empty; collect_inst_stats();}voidsegment_t::tick_ready_stats(){ ready_list->tick_stats(); if (segment_number != 0) { current_ops_ready = 0; for (iq_it_list_iterator i=head(); i.notnull(); i=i.next()) { if ((*i)->ops_ready()) { ++current_ops_ready; ++cum_ops_ready[(*i)->thread_number()]; } } } else { current_ops_ready = ready_list->count(); for (int t = 0; t < number_of_threads; ++t) cum_ops_ready[t] += ready_list->count(t); }}boolRQ_Issue_Policy::goes_before(FullCPU *cpu, res_list<IQStation>::iterator &first, res_list<IQStation>::iterator &second, bool use_thread_priorities){ bool rv = false; unsigned first_p = cpu->thread_info[first->thread_number()].priority; unsigned second_p = cpu->thread_info[second->thread_number()].priority; if (use_thread_priorities) { // if first has higher priority... if (first_p > second_p) { rv = true; } else if (second_p > first_p) { // second higher priority rv = false; } else if (first->seq < second->seq) { // same priority rv = true; } } else { if (first->seq < second->seq) rv = true; } return rv;}boolRQ_Seg_Policy::goes_before(FullCPU *cpu, res_list<IQStation>::iterator &first, res_list<IQStation>::iterator &second, bool use_thread_priorities){ if (use_dest_sort) { unsigned dest_seg[] = {0, 0}; dest_seg[0] = first->dest_seg; dest_seg[1] = second->dest_seg; // if the first's distance is larger than the second's distance, // then the first should go before the second if (dest_seg[0] < dest_seg[1]) return true; if (dest_seg[0] > dest_seg[1]) return false; } // If the destinations are the same, use age... if (first->seq < second->seq) return true; return false;}voidsegment_t::enqueue(iq_iterator &p){ p->rq_entry = ready_list->enqueue(p); p->queued = true;}voidsegment_t::tick(){ // We have to do this if we have a dynamic ordering... ready_list->resort();}//// Determine the "correct" segment for this instruction//unsignedsegment_t::proper_segment(iq_iterator &inst){ unsigned my_seg = 0; for (int i = 0; i < TheISA::MaxInstSrcRegs; ++i) { unsigned new_seg = 0; if (!inst->idep_ready[i]) { if (inst->idep_info[i].chained) { unsigned c = inst->idep_info[i].follows_chain; unsigned head_level = (*chain_info)[c].head_level; if (head_level == num_segments - 1) { new_seg = head_level; } else { // // Use the "cumulative" thresholds here // new_seg = num_segments - 1; // default unsigned inst_offset = seg_queue->get_thresh(head_level) + inst->idep_info[i].delay; for (unsigned s = head_level; s < num_segments - 1; ++s) { if (inst_offset < seg_queue->get_thresh(s + 1)) { new_seg = s; break; } } } } else { new_seg = num_segments - 1; // default for (int s = 0; s < num_segments; ++s) { if (inst->idep_info[i].delay < seg_queue->get_thresh(s)) { new_seg = s; break; } } } } // make sure we don't blow our top... if (new_seg >= num_segments) new_seg = num_segments - 1; // we're looking for the "highest" segment if (new_seg > my_seg) my_seg = new_seg; } return my_seg;}voidsegment_t::dump_chain(unsigned c){ iq_it_list_iterator i = chains[c]->head(); for (; i.notnull(); i = i.next()) cout << (*i)->seq << " ";}voidsegment_t::dump_chains(){ for (int i = 0; i < num_chains; ++i) { if (chains[i]->count()) { cout << "Chain " << i << ": "; dump_chain(i); cout << endl; } }}//// Normal segment dump//voidsegment_t::dump(int length){ cprintf("=========================================================\n" "Segment %u (thresh=%u)\n" " Total Instructions: %u\n" " By thread: [", segment_number, threshold, queue->count()); for (unsigned i = 0; i < seg_queue->cpu->number_of_threads; ++i) { cprintf("%u", insts[i]); if (i == seg_queue->cpu->number_of_threads - 1) cout << "]\n"; else cout <<", "; } cout << "---------------------------------------------------------\n"; iq_iterator_list *sorted_queue = new iq_iterator_list(size, true, 0); // Place each instruction into the sorted_queue for (iq_it_list_iterator i = queue->head(); i.notnull(); i = i.next()) { // find the right spot for this inst if (sorted_queue->empty() || (*i)->seq < (*(sorted_queue->head()))->seq) { // Special case... place this inst up front... sorted_queue->insert_after(0, *i); } else { bool done = false; iq_it_list_iterator prev_spot = 0; iq_it_list_iterator j = sorted_queue->head(); for (; j.notnull(); j = j.next()) { if ((*i)->seq < (*j)->seq) { sorted_queue->insert_after(prev_spot, *i); done = true; break; } prev_spot = j; } if (!done) sorted_queue->add_tail(*i); } } iq_it_list_iterator i = sorted_queue->head(); for (; i.notnull(); i = i.next()) { cout << " "; // Cheating a little here (*i)->iq_segmented_dump(length); } delete sorted_queue;}//// Special one-line dump for looking at massive amounts of data//voidsegment_t::short_dump(){ cout << "=========================================================\n"; cprintf("Segment %u (%u insts) (thresh=%u)\n", segment_number, queue->count(), threshold); iq_iterator_list *sorted_queue = new iq_iterator_list(size, true, 0); // Place each instruction into the sorted_queue for (iq_it_list_iterator i = queue->head(); i.notnull(); i = i.next()) { // find the right spot for this inst if (sorted_queue->empty() || (*i)->seq < (*(sorted_queue->head()))->seq) { // Special case... place this inst up front... sorted_queue->insert_after(0, *i); } else { bool done = false; iq_it_list_iterator prev_spot = 0; iq_it_list_iterator j = sorted_queue->head(); for (; j.notnull(); j = j.next()) { if ((*i)->seq < (*j)->seq) { sorted_queue->insert_after(prev_spot, *i); done = true; break; } prev_spot = j; } if (!done) sorted_queue->add_tail(*i); } } iq_it_list_iterator i = sorted_queue->head(); for (; i.notnull(); i = i.next()) { cout << " "; // Cheating a little here (*i)->iq_segmented_short_dump(); } delete sorted_queue;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -