IBucket *Pipeline::nextItem() { while(1) { if (buffer.empty()) { #ifdef DEBUG // It should not be possible to propagate more buckets clearItems(); I(buffer.empty()); #endif return 0; } if( ((buffer.top())->getClock() + PipeLength) > globalClock ) return 0; IBucket *b = buffer.top(); buffer.pop(); I(!b->empty()); if (!b->cleanItem) { I(!b->empty()); I(b->top() != 0); return b; } I(b->cleanItem); I(!b->empty()); I(b->top() == 0); b->pop(); I(b->empty()); cleanBucketPool.push_back(b); } I(0); }
int GProcessor::issue(PipeQueue &pipeQ) { int i=0; // Instructions executed counter int j=0; // Fake Instructions counter I(!pipeQ.instQueue.empty()); if(!replayQ.empty()) { issueFromReplayQ(); nStall[ReplayStall]->add(RealisticWidth); return 0; // we issued 0 from the instQ; // FIXME:check if we can issue from replayQ and // fetchQ during the same cycle } do{ IBucket *bucket = pipeQ.instQueue.top(); do{ I(!bucket->empty()); if( i >= IssueWidth ) { return i+j; } I(!bucket->empty()); DInst *dinst = bucket->top(); #ifdef TASKSCALAR if (!dinst->isFake()) { if (dinst->getLVID()==0 || dinst->getLVID()->isKilled()) { // Task got killed. Just swallow the instruction dinst->killSilently(); bucket->pop(); j++; continue; } } #endif StallCause c = addInst(dinst); if (c != NoStall) { if (i < RealisticWidth) nStall[c]->add(RealisticWidth - i); return i+j; } i++; bucket->pop(); }while(!bucket->empty()); pipeQ.pipeLine.doneItem(bucket); pipeQ.instQueue.pop(); }while(!pipeQ.instQueue.empty()); return i+j; }
void Processor::purgeInstructionWindow() { /* while(!pipeQ.instQueue.empty()); { IBucket* bucket = pipeQ.instQueue.top(); while(!bucket->empty()) { bucket->top()->killSilently(); bucket->pop(); } // pipeQ.pipeLine.doneItem(bucket); pipeQ.instQueue.pop(); }*/ while(pipeQ.pipeLine.hasOutstandingItems()) { IBucket* bucket = pipeQ.pipeLine.nextItem(); while(!bucket->empty()) { bucket->top()->killSilently(); bucket->pop(); } pipeQ.pipeLine.doneItem(bucket); } pipeQ.pipeLine.clearItems(); }
int32_t GProcessor::issue(PipeQueue &pipeQ) { int32_t i=0; // Instructions executed counter int32_t j=0; // Fake Instructions counter I(!pipeQ.instQueue.empty()); if(!replayQ.empty()) { issueFromReplayQ(); nStall[ReplayStall]->add(RealisticWidth); return 0; // we issued 0 from the instQ; // FIXME:check if we can issue from replayQ and // fetchQ during the same cycle } do { IBucket *bucket = pipeQ.instQueue.top(); do { I(!bucket->empty()); if( i >= IssueWidth ) { return i+j; } I(!bucket->empty()); DInst *dinst = bucket->top(); StallCause c = addInst(dinst); if (c != NoStall) { if (i < RealisticWidth) nStall[c]->add(RealisticWidth - i); return i+j; } i++; bucket->pop(); } while(!bucket->empty()); pipeQ.pipeLine.doneItem(bucket); pipeQ.instQueue.pop(); } while(!pipeQ.instQueue.empty()); return i+j; }
bool GPUSMProcessor::advance_clock(FlodID fid) { if (!active) { // time to remove from the running queue TaskHandler::removeFromRunning(cpu_id); return false; } fetch(fid); if (!busy) return false; clockTicks.inc(); setWallClock(); if (unlikely(throttlingRatio>1)) { throttling_cntr++; uint32_t skip = ceil(throttlingRatio/getTurboRatioGPU()); if (throttling_cntr < skip) { return true; } throttling_cntr = 1; } // ID Stage (insert to instQueue) if (spaceInInstQueue >= FetchWidth) { //MSG("\nFor CPU %d:",getId()); IBucket *bucket = pipeQ.pipeLine.nextItem(); if( bucket ) { I(!bucket->empty()); spaceInInstQueue -= bucket->size(); pipeQ.instQueue.push(bucket); }else{ noFetch2.inc(); } }else{ noFetch.inc(); } // RENAME Stage if ( !pipeQ.instQueue.empty() ) { // FIXME: Clear the per PE counter spaceInInstQueue += issue(pipeQ); }else if (ROB.empty() && rROB.empty()) { //I(0); // Still busy if we have some in-flight requests busy = pipeQ.pipeLine.hasOutstandingItems(); return true; } retire(); return true; }
void Processor::advanceClock() { clockTicks++; // GMSG(!ROB.empty(),"robTop %d Ul %d Us %d Ub %d",ROB.getIdFromTop(0) // ,unresolvedLoad, unresolvedStore, unresolvedBranch); // Fetch Stage if (IFID.hasWork() && !IsBusyWaiting()) { IBucket *bucket = pipeQ.pipeLine.newItem(); if( bucket ) { IFID.fetch(bucket); } } // ID Stage (insert to instQueue) if (spaceInInstQueue >= FetchWidth) { IBucket *bucket = pipeQ.pipeLine.nextItem(); if( bucket ) { I(!bucket->empty()); // I(bucket->top()->getInst()->getAddr()); spaceInInstQueue -= bucket->size(); pipeQ.instQueue.push(bucket); }else{ noFetch2.inc(); } }else{ noFetch.inc(); } // RENAME Stage if ( !pipeQ.instQueue.empty() ) { spaceInInstQueue += issue(pipeQ); // spaceInInstQueue += issue(pipeQ); } //transactional region while(TMInterface::HasTransfers(getId())) { bool isRead, isRequired; VAddr address; size_t accessSize; TMInterface::GetTransferInfo(isRead, isRequired, address, accessSize); CallbackBase* cb = NotifyCompletedTransCB::create(this,getId(),isRead,address); if(getMemorySystem()->getMemoryOS()->insertTransAccess(isRead,isRequired,address,accessSize,cb)) { TMInterface::AcceptTransfer(); } else { cb->destroy(); TMInterface::DenyTransfer(); break; } } retire(); }
void GPUSMProcessor::fetch(FlowID fid) { I(eint); I(active); // Do not block fetch for a branch miss if( IFID.isBlocked(0)) { busy = true; }else{ IBucket *bucket = pipeQ.pipeLine.newItem(); if( bucket ) { IFID.fetch(bucket, eint, fid); if (!bucket->empty()) { busy = true; } } } }
void Pipeline::clearItems() { while( !received.empty() ) { IBucket *b = received.top(); if(b->getPipelineId() != minItemCntr){ break; } received.pop(); minItemCntr++; if( b->empty() ) doneItem(b); else buffer.push(b); } }
void Processor::advanceClock() { #ifdef TS_STALL if (isStall()) return; #endif clockTicks++; // GMSG(!ROB.empty(),"robTop %d Ul %d Us %d Ub %d",ROB.getIdFromTop(0) // ,unresolvedLoad, unresolvedStore, unresolvedBranch); // Fetch Stage if (IFID.hasWork() ) { IBucket *bucket = pipeQ.pipeLine.newItem(); if( bucket ) { IFID.fetch(bucket); } } // ID Stage (insert to instQueue) if (spaceInInstQueue >= FetchWidth) { IBucket *bucket = pipeQ.pipeLine.nextItem(); if( bucket ) { I(!bucket->empty()); // I(bucket->top()->getInst()->getAddr()); spaceInInstQueue -= bucket->size(); pipeQ.instQueue.push(bucket); }else{ noFetch2.inc(); } }else{ noFetch.inc(); } // RENAME Stage if ( !pipeQ.instQueue.empty() ) { spaceInInstQueue += issue(pipeQ); // spaceInInstQueue += issue(pipeQ); } retire(); }