⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iq_seg.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 3 页
字号:
	    .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 + -