Hey Mike, I'm working on ALPHA+inorder myself (but on a slightly older gem5 version) and I made it work. The pipeline_traits you mentioned are used (at least as I see them) only as a template if you wanted to change the architecture. The file that you need to look into is pipeline_traits.hh The variable you need to change in order to run more than one thread is,as you mentioned, MaxThreads.
Korey mentioned in his response adding stages. I need to that too. So for that you'll need to change the variable NumStages in pipeline_traits.hh. and to modify createFrontSked and createBackSked in cpu.cc Korey already said all that, but I'd like to provide you with an example from my modifications. I use 12 stages pipe (The code crashes if I try more than that) In the front end I've just moved some of the functionality around. RSkedPtr InOrderCPU::createFrontEndSked() { RSkedPtr res_sked = new ResourceSked(); int stage_num = 0; StageScheduler F(res_sked, stage_num++); StageScheduler D(res_sked, stage_num++); // FETCH F.needs(FetchSeq, FetchSeqUnit::AssignNextPC); F.needs(ICache, FetchUnit::InitiateFetch); F.needs(ICache, FetchUnit::CompleteFetch); // F.needs(Decode, DecodeUnit::DecodeInst); F.needs(BPred, BranchPredictor::PredictBranch); F.needs(FetchSeq, FetchSeqUnit::UpdateTargetPC); // DECODE // D.needs(ICache, FetchUnit::CompleteFetch); D.needs(Decode, DecodeUnit::DecodeInst); // D.needs(BPred, BranchPredictor::PredictBranch); // D.needs(FetchSeq, FetchSeqUnit::UpdateTargetPC); DPRINTF(SkedCache, "Resource Sked created for instruction Front End\n"); return res_sked; } In the Back end I added some used stages (I only care about the length of the pipe rather than the functionality of each stage, as long as the execution units are near the end). You can also add some new functionalities there as I did (look for my name in the comments) RSkedPtr InOrderCPU::createBackEndSked(DynInstPtr inst) { RSkedPtr res_sked = lookupSked(inst); if (res_sked != NULL) { DPRINTF(SkedCache, "Found %s in sked cache.\n", inst->instName()); return res_sked; } else { res_sked = new ResourceSked(); } int stage_num = ThePipeline::BackEndStartStage; //Y.H. Nacson - Schedules empty stages - should be written more efficiently StageScheduler UnusedStage2(res_sked, 2); StageScheduler UnusedStage3(res_sked, 3); StageScheduler UnusedStage4(res_sked, 4); StageScheduler UnusedStage5(res_sked, 5); StageScheduler UnusedStage6(res_sked, 6); StageScheduler UnusedStage7(res_sked, 7); StageScheduler UnusedStage8(res_sked, 8); StageScheduler X(res_sked, stage_num++); StageScheduler M(res_sked, stage_num++); StageScheduler W(res_sked, stage_num++); if (!inst->staticInst) { warn_once("Static Instruction Object Not Set. Can't Create" " Back End Schedule"); return NULL; } // EXECUTE X.needs(RegManager, UseDefUnit::MarkDestRegs); for (int idx=0; idx < inst->numSrcRegs(); idx++) { if (!idx || !inst->isStore()) { X.needs(RegManager, UseDefUnit::ReadSrcReg, idx); } } //@todo: schedule non-spec insts to operate on this cycle // as long as all previous insts are done if ( inst->isNonSpeculative() ) { // skip execution of non speculative insts until later } else if ( inst->isMemRef() ) { if ( inst->isLoad() ) { X.needs(AGEN, AGENUnit::GenerateAddr); } } else if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) { X.needs(MDU, MultDivUnit::StartMultDiv); } else { X.needs(ExecUnit, ExecutionUnit::ExecuteInst); } // MEMORY if (!inst->isNonSpeculative()) { if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) { M.needs(MDU, MultDivUnit::EndMultDiv); } if ( inst->isLoad() ) { M.needs(DCache, CacheUnit::InitiateReadData); if (inst->splitInst) M.needs(DCache, CacheUnit::InitSecondSplitRead); M.needs(DCache, CacheUnit::CacheDelay); //Y.H. Nacson - adding the cache delay function. } else if ( inst->isStore() ) { for (int i = 1; i < inst->numSrcRegs(); i++ ) { M.needs(RegManager, UseDefUnit::ReadSrcReg, i); } M.needs(AGEN, AGENUnit::GenerateAddr); M.needs(DCache, CacheUnit::InitiateWriteData); if (inst->splitInst) M.needs(DCache, CacheUnit::InitSecondSplitWrite); if (inst->isStoreConditional()) M.needs(DCache, CacheUnit::CacheDelay); //Y.H. Nacson - adding the cache delay function. } } // WRITEBACK if (!inst->isNonSpeculative()) { if ( inst->isLoad() ) { W.needs(DCache, CacheUnit::CompleteReadData); if (inst->splitInst) W.needs(DCache, CacheUnit::CompleteSecondSplitRead); } else if ( inst->isStore() ) { W.needs(DCache, CacheUnit::CompleteWriteData); if (inst->splitInst) W.needs(DCache, CacheUnit::CompleteSecondSplitWrite); } } else { // Finally, Execute Speculative Data if (inst->isMemRef()) { if (inst->isLoad()) { W.needs(AGEN, AGENUnit::GenerateAddr); W.needs(DCache, CacheUnit::InitiateReadData); if (inst->splitInst) W.needs(DCache, CacheUnit::InitSecondSplitRead); W.needs(DCache, CacheUnit::CompleteReadData); if (inst->splitInst) W.needs(DCache, CacheUnit::CompleteSecondSplitRead); } else if (inst->isStore()) { if ( inst->numSrcRegs() >= 2 ) { W.needs(RegManager, UseDefUnit::ReadSrcReg, 1); } W.needs(AGEN, AGENUnit::GenerateAddr); W.needs(DCache, CacheUnit::InitiateWriteData); if (inst->splitInst) W.needs(DCache, CacheUnit::InitSecondSplitWrite); W.needs(DCache, CacheUnit::CompleteWriteData); if (inst->splitInst) W.needs(DCache, CacheUnit::CompleteSecondSplitWrite); } } else { W.needs(ExecUnit, ExecutionUnit::ExecuteInst); } } W.needs(Grad, GraduationUnit::CheckFault); for (int idx=0; idx < inst->numDestRegs(); idx++) { W.needs(RegManager, UseDefUnit::WriteDestReg, idx); } if (inst->isControl()) W.needs(BPred, BranchPredictor::UpdatePredictor); W.needs(Grad, GraduationUnit::GraduateInst); // Insert Back Schedule into our cache of // resource schedules addToSkedCache(inst, res_sked); DPRINTF(SkedCache, "Back End Sked Created for instruction: %s (%08p)\n", inst->instName(), inst->getMachInst()); res_sked->print(); return res_sked; } Yuval -----Original Message----- From: gem5-users-boun...@gem5.org [mailto:gem5-users-boun...@gem5.org] On Behalf Of Michael Levenhagen Sent: Wednesday, 26 September, 2012 20:51 To: gem5 users mailing list Subject: [gem5-users] SMT status With which ISAs and CPU models does SMT work? I've tried running different configs and it appears that only "ALPHA + detailed" works. I chased down a panic when I attempt to use "ALPHA+inorder" and it says I need to increase 'MaxThreads'. I looked at the "inorder" cpu code and notice that pipeline_traits.5stage.hh, pipeline_traits.9stage.hh and pipeline_traits.9stage.smt2.hh, have MaxThreads set to something greater than 1. Does SMT work "reliably" with "ALPHA+detailed"? Would "ALPHA+inorder" work with a code configuration change? Mike Levenhagen _______________________________________________ gem5-users mailing list gem5-users@gem5.org http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users _______________________________________________ gem5-users mailing list gem5-users@gem5.org http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users