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

📄 issue.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 4 页
字号:
#endif		//		//  RR for FU pool if there isn't a 1:1 match between		//  Queues and FU pools...		//		if (numIQueues != numFUPools)		    current_fu_pool = (current_fu_pool + 1) % numFUPools;		++n_issued;		++issued_by_thread[thread];		++expected_inorder_seq_num;		issue_delay_dist[inst->opClass()]		    .sample(curTick - ready_ts);		queue_res_dist[inst->opClass()]		    .sample(curTick - dispatch_ts);		//		//  Update INSTRUCTION statistics		//		if (source == iq)		    update_exe_inst_stats(inst);		//		//  Update OPERATION statistics		//		++issued_ops[thread];	    }	}	//	//  STEP #5:	//	//  Rotate through the IQ's	//  (first to check to see if this ready-list is empty)	//	if (source == iq) {	    bool no_rdy_insts = iq_rq_iterator[current_iq].isnull();	    bool no_bw        = (IQ[current_iq]->issue_bw() == 0);	    if (no_rdy_insts || no_bw) {		//  mark this queue done, check for all done		done_with_iq = done_list.markDone(current_iq);		if (no_rdy_insts) {		    if (IQ[current_iq]->iw_count()) {			// iq not empty, but no ready insts...			if (floss_state.issue_end_cause[0] ==			    ISSUE_CAUSE_NOT_SET)			{			    //			    //  Either the oldest instruction is waiting for			    //  it's inputs or some other IQ-related problem			    //			    evil_inst = IQ[current_iq]->oldest();			    if (!evil_inst->ops_ready()) {				floss_state.issue_end_cause[0] = ISSUE_DEPS;				if (!find_idep_to_blame(evil_inst, 0))				    floss_state.issue_end_cause[0] = ISSUE_IQ;			    } else {				floss_state.issue_end_cause[0] = ISSUE_IQ;			    }			}		    }		    else {			// iq empty			SET_FIRST_FLOSS_CAUSE(floss_state.issue_end_cause[0],					      ISSUE_NO_INSN);		    }		}		else {		    //		    //  Must have been BW...		    //		    SET_FIRST_FLOSS_CAUSE(floss_state.issue_end_cause[0],					  ISSUE_BW);		}	    }#if ISSUE_OLDEST == 0	    if (!done_with_iq)		current_iq = (current_iq + 1) % numIQueues;#endif	}	//	//  STEP #6:	//	//  When we run out of bandwidth, indicate	//  that we are done issuing from the IQ & LSQ	//	if (n_issued >= issue_width) {	    done_with_iq = true;	    done_with_lsq = true;	}    } while (!done_with_iq || !done_with_sb || !done_with_lsq);    //    //  Delete the allocated lists...    //    delete[] iq_rq_iterator;    delete[] hp_rq_it_list;    delete[] hp_done;#if DUMP_ISSUE    if (!issued_list.empty()) {	issued_list.sort();	list<issue_info>::iterator i = issued_list.begin();	list<issue_info>::iterator end = issued_list.end();	for (; i != end; ++i)	{	    cerr << "   #" << i->seq << " (clust " << i->clust << ") "		 << i->inst << endl;	}    }#endif    //    //    //  We've issued n_issued instructions from the IQ or LSQ    //    n_issued_dist[n_issued]++;    if (n_issued == issue_width) {	//	//  Issue BW limit reached... blame loss on BW only if there are	//  no ready instructions	//	if (floss_state.issue_end_cause[0] != ISSUE_IQ) {	    //	    //  NOTE:  these causes over-ride any previously-set cause	    //	    if (n_ready == 0) {		if (IQNumInstructions() != 0) {		    floss_state.issue_end_cause[0] = ISSUE_DEPS;		    evil_inst = IQOldestInstruction();		    if (!find_idep_to_blame(evil_inst, 0)) {			floss_state.issue_end_cause[0] = ISSUE_IQ;		    }		} else {		    floss_state.issue_end_cause[0] = ISSUE_NO_INSN;		}	    } else {		floss_state.issue_end_cause[0] = ISSUE_BW;	    }	}    } else {	//	//  We have issue BW left:	//     (1) We must have tried to issue from the IQ	//           ==> issue_end_cause is set in Sep #1	//     (2) OR, we must have tried to issue from the LSQ	//           ==> issue_end_cause may not be set	//                 -> No instructions	//                 -> No instructions ready	//                 -> issue trouble... cause will be set in lsq_issue	//     (3) OR, we only issued from the SB	//           ==> issue_end_cause is set in Sep #1	//     (4) OR, we were issuing inorder	//           ==> ISSUE_INORDER	//	if (floss_state.issue_end_cause[0] == ISSUE_CAUSE_NOT_SET) {	    if (LSQ->count() != 0) {		floss_state.issue_end_cause[0] = ISSUE_DEPS;		evil_inst = LSQ->oldest();		if (!find_idep_to_blame(evil_inst, 0))		    floss_state.issue_end_cause[0] = ISSUE_IQ;	    } else {		floss_state.issue_end_cause[0] = ISSUE_NO_INSN;	    }	}    }#if DEBUG_FLOSS    if (floss_state.issue_end_cause[0] == ISSUE_CAUSE_NOT_SET)        panic("cause not set");#endif}// voidFullCPU::issue_init(){    int i;#if 0    for (i = 0; i < SMT_MAX_THREADS; i++)	store_info[i] = new(lsq_store_info_t)[LSQ_size];#endif    for (i = 0; i < Num_OpClasses; ++i)	unissued_names[i] = opClassStrings[i];    unissued_names[Num_OpClasses]   = "DCache_Blocked";    unissued_names[Num_OpClasses + 1] = "Too_Young";#if REMOVE_WP_LOADS    cerr << "NOT Issuing misspeculated loads..." << endl;#endif}voidFullCPU::issueRegStats(){    using namespace Stats;    com_inst.resize(number_of_threads);    com_loads.resize(number_of_threads);    for (int i = 0; i < number_of_threads; ++i) {	com_inst[i] = 0;	com_loads[i] = 0;    }    stat_com_inst	.init(number_of_threads)	.name(name() + ".COM:count")	.desc("Number of instructions committed")	.flags(total)	;    stat_com_swp	.init(number_of_threads)	.name(name() + ".COM:swp_count")	.desc("Number of s/w prefetches committed")	.flags(total)	;    stat_com_refs	.init(number_of_threads)	.name(name() +  ".COM:refs")	.desc("Number of memory references committed")	.flags(total)	;    stat_com_loads	.init(number_of_threads)	.name(name() +  ".COM:loads")	.desc("Number of loads committed")	.flags(total)	;    stat_com_membars	.init(number_of_threads)	.name(name() +  ".COM:membars")	.desc("Number of memory barriers committed")	.flags(total)	;    stat_com_branches	.init(number_of_threads)	.name(name() + ".COM:branches")	.desc("Number of branches committed")	.flags(total)	;    //    //  these will count the number of PROGRAM instructions    //  (NOT "operations") issued... ie. EA-Comp ops are not counted    //    exe_inst	.init(number_of_threads)	.name(name() + ".ISSUE:count")	.desc("number of insts issued")	.flags(total)	;    exe_swp	.init(number_of_threads)	.name(name() + ".ISSUE:swp")	.desc("number of swp insts issued")	.flags(total)	;    exe_nop	.init(number_of_threads)	.name(name() + ".ISSUE:nop")	.desc("number of nop insts issued")	.flags(total)	;    exe_refs	.init(number_of_threads)	.name(name() + ".ISSUE:refs")	.desc("number of memory reference insts issued")	.flags(total)	;    exe_loads	.init(number_of_threads)	.name(name() + ".ISSUE:loads")	.desc("number of load insts issued")	.flags(total)	;    exe_branches	.init(number_of_threads)	.name(name() + ".ISSUE:branches")	.desc("Number of branches issued")	.flags(total)	;    issued_ops	.init(number_of_threads)	.name(name() + ".ISSUE:op_count")	.desc("number of insts issued")	.flags(total)	;    n_issued_dist	.init(issue_width + 1)	.name(name() + ".ISSUE:issued_per_cycle")	.desc("Number of insts issued each cycle")	.flags(total | pdf | dist)	;    fu_busy	.init(number_of_threads)	.name(name() + ".ISSUE:fu_busy_cnt")	.desc("FU busy when requested")	.flags(total)	;    stat_fu_busy	.init(Num_OpClasses)	.name(name() + ".ISSUE:fu_full")	.desc("attempts to use FU when none available")	.flags(pdf | dist)	;    for (int i=0; i < Num_OpClasses; ++i) {	stat_fu_busy.subname(i, opClassStrings[i]);    }    stat_fuBusy	.init(numIQueues, Num_OpClasses)	.name(name() + ".ISSUE:IQ")	.flags(pdf | dist)	;    for (int q = 0; q < numIQueues; ++q) {	stringstream label,desc;	label << q << ":fu_full";	desc <<  " attempts to issue to FU from pool #" << q <<	    "when none available";	stat_fuBusy	    .subname(q, label.str())	    .subdesc(q, desc.str())	    ;    }    stat_fuBusy.ysubnames(opClassStrings);    dist_unissued	.init(Num_OpClasses+2)	.name(name() + ".ISSUE:unissued_cause")	.desc("Reason ready instruction not issued")	.flags(pdf | dist)	;    for (int i=0; i < (Num_OpClasses + 2); ++i) {	dist_unissued.subname(i, unissued_names[i]);    }    stat_issued_inst_type	.init(number_of_threads,Num_OpClasses)	.name(name() + ".ISSUE:FU_type")	.desc("Type of FU issued")	.flags(total | pdf | dist)	;    stat_issued_inst_type.ysubnames(opClassStrings);    //    //  How long did instructions for a particular FU type wait prior to issue    //    issue_delay_dist	.init(Num_OpClasses,0,99,2)	.name(name() + ".ISSUE:")	.desc("cycles from operands ready to issue")	.flags(pdf | cdf)	;    for (int i=0; i<Num_OpClasses; ++i) {	stringstream subname;	subname << opClassStrings[i] << "_delay";	issue_delay_dist.subname(i, subname.str());    }    //    //  Other stats    //    lsq_forw_loads	.init(number_of_threads)	.name(name() + ".LSQ:forw_loads")	.desc("number of loads forwarded via LSQ")	.flags(total)	;    inv_addr_loads	.init(number_of_threads)	.name(name() + ".ISSUE:addr_loads")	.desc("number of invalid-address loads")	.flags(total)	;    inv_addr_swpfs	.init(number_of_threads)	.name(name() + ".ISSUE:addr_swpfs")	.desc("number of invalid-address SW prefetches")	.flags(total)	;    queue_res_dist	.init(Num_OpClasses, 0, 99, 2)	.name(name() + ".IQ:residence:")	.desc("cycles from dispatch to issue")	.flags(total | pdf | cdf )	;    for (int i = 0; i < Num_OpClasses; ++i) {	queue_res_dist.subname(i, opClassStrings[i]);    }    lsq_blocked_loads	.init(number_of_threads)	.name(name() + ".LSQ:blocked_loads")	.desc("number of ready loads not issued due to memory disambiguation")	.flags(total)	;    lsqInversion	.name(name() + ".ISSUE:lsq_invert")	.desc("Number of times LSQ instruction issued early")	;}voidFullCPU::issueRegFormulas(){    using namespace Stats;    misspec_cnt	.name(name() + ".ISSUE:misspec_cnt")	.desc("Number of misspeculated insts issued")	.flags(total)	;    misspec_cnt = exe_inst - stat_com_inst;    misspec_ipc	.name(name() + ".ISSUE:MSIPC")	.desc("Misspec issue rate")	.flags(total)	;    misspec_ipc = misspec_cnt / numCycles;    issue_rate	.name(name() + ".ISSUE:rate")	.desc("Inst issue rate")	.flags(total)	;    issue_rate = exe_inst / numCycles;    issue_stores	.name(name() + ".ISSUE:stores")	.desc("Number of stores issued")	.flags(total)	;    issue_stores = exe_refs - exe_loads;    issue_op_rate	.name(name() + ".ISSUE:op_rate")	.desc("Operation issue rate")	.flags(total)	;    issue_op_rate = issued_ops / numCycles;    fu_busy_rate	.name(name() + ".ISSUE:fu_busy_rate")	.desc("FU busy rate (busy events/executed inst)")	.flags(total)	;    fu_busy_rate = fu_busy / exe_inst;    //    //  Commit-stage statistics    //  (we include these here because we _count_ them here)    //    commit_stores	.name(name() + ".COM:stores")	.desc("Number of stores committed")	.flags(total)	;    commit_stores = stat_com_refs - stat_com_loads;    commit_ipc	.name(name() + ".COM:IPC")	.desc("Committed instructions per cycle")	.flags(total)	;    commit_ipc = stat_com_inst / numCycles;    commit_ipb	.name(name() + ".COM:IPB")	.desc("Committed instructions per branch")	.flags(total)	;    commit_ipb = stat_com_inst / stat_com_branches;    lsq_inv_rate	.name(name() + ".ISSUE:lsq_inv_rate")	.desc("Early LSQ issues per cycle")	;    lsq_inv_rate = lsqInversion / numCycles;}/************************************************************** *                                                            * *  Collect instruction statistics                            * *                                                            * **************************************************************/voidFullCPU::update_exe_inst_stats(DynInst *inst){    int thread_number = inst->thread_number;    //    //  Pick off the software prefetches    //#ifdef TARGET_ALPHA    if (inst->isDataPrefetch())	exe_swp[thread_number]++;    else	exe_inst[thread_number]++;#else    exe_inst[thread_number]++;#endif    //    //  Control operations    //    if (inst->isControl())	exe_branches[thread_number]++;    //    //  Memory operations    //    if (inst->isMemRef()) {	exe_refs[thread_number]++;	if (inst->isLoad())	    exe_loads[thread_number]++;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -