bool CommonMigrator::TryMigration( NVMainRequest *request, bool atomic ) { begin_cycle_ = GetEventQueue()->GetCurrentCycle(); bool rv = true; //translate this object to NVMain type if( NVMTypeMatches(NVMain) ) { /* Ensure the Migrator translator is used. */ //parent module is who issue migration?? Migrator *migratorTranslator = dynamic_cast<Migrator *>(parent->GetTrampoline( )->GetDecoder( )); assert( migratorTranslator != NULL ); /* Migrations in progress must be served from the buffers during migration. */ if( GetCurrentHookType( ) == NVMHOOK_PREISSUE && migratorTranslator->IsBuffered( request->address ) ) { /* Short circuit this request so it is not queued. */ rv = false; /* Complete the request, adding some buffer read latency. */ GetEventQueue( )->InsertEvent( EventResponse, parent->GetTrampoline( ), request, GetEventQueue()->GetCurrentCycle()+bufferReadLatency ); bufferedReads++; return rv; } /* Don't inject results before the original is issued to prevent deadlock */ if( GetCurrentHookType( ) != NVMHOOK_POSTISSUE ) { return rv; } /* See if any migration is possible (i.e., no migration is in progress) */ bool migrationPossible = false; if( !migratorTranslator->Migrating( ) && !migratorTranslator->IsMigrated( request->address ) && request->address.GetChannel( ) != promotionChannel ) { migrationPossible = true; } if( migrationPossible ) { assert( !demoBuffered && !promoBuffered ); /* * Note: once IssueCommand is called, this hook may receive * a different parent, but fail the NVMTypeMatch check. As a * result we need to save a pointer to the NVMain class we * are issuing requests to. */ NVMObject *savedParent = parent->GetTrampoline( ); /* Discard the unused column address. */ uint64_t row, bank, rank, channel, subarray; request->address.GetTranslatedAddress( &row, NULL, &bank, &rank, &channel, &subarray ); uint64_t promoteeAddress = migratorTranslator->ReverseTranslate( row, 0, bank, rank, channel, subarray ); promotee.SetPhysicalAddress( promoteeAddress ); promotee.SetTranslatedAddress( row, 0, bank, rank, channel, subarray ); /* Pick a victim to replace. */ ChooseVictim( migratorTranslator, promotee, demotee ); assert( migratorTranslator->IsMigrated( demotee ) == false ); assert( migratorTranslator->IsMigrated( promotee ) == false ); if( atomic ) { migratorTranslator->StartMigration( request->address, demotee ); migratorTranslator->SetMigrationState( promotee, MIGRATION_DONE ); migratorTranslator->SetMigrationState( demotee, MIGRATION_DONE ); } /* Lastly, make sure we can queue the migration requests. */ else if( CheckIssuable( promotee, READ ) && CheckIssuable( demotee, READ ) ) { migratorTranslator->StartMigration( request->address, demotee ); promoRequest = new NVMainRequest( ); demoRequest = new NVMainRequest( ); promoRequest->address = promotee; promoRequest->type = READ; promoRequest->tag = MIG_READ_TAG; promoRequest->burstCount = numCols; demoRequest->address = demotee; demoRequest->type = READ; demoRequest->tag = MIG_READ_TAG; demoRequest->burstCount = numCols; promoRequest->owner = savedParent; demoRequest->owner = savedParent; savedParent->IssueCommand( promoRequest ); savedParent->IssueCommand( demoRequest ); } else { queueWaits++; } } } return rv; }
bool MultiQueueMigrator::TryMigration( NVMainRequest *request, bool atomic ) { // std::cout<<"\nMultiQueueMigrator::TryMigration ---- addr: "<<std::hex<<request->address.GetPhysicalAddress()<<"\n"<<std::endl; bool rv = true; if( NVMTypeMatches(NVMain) ) { //std::cout<<"migration:"<<std::endl; /* Ensure the Migrator translator is used. */ MQMigrator *migratorTranslator = dynamic_cast<MQMigrator *>(parent->GetTrampoline( )->GetDecoder( )); assert( migratorTranslator != NULL ); /* Migrations in progress must be served from the buffers during migration. */ if( GetCurrentHookType( ) == NVMHOOK_PREISSUE && migratorTranslator->IsBuffered( request->address ) ) { /* Short circuit this request so it is not queued. */ rv = false; /* Complete the request, adding some buffer read latency. */ GetEventQueue( )->InsertEvent( EventResponse, parent->GetTrampoline( ), request, GetEventQueue()->GetCurrentCycle()+bufferReadLatency ); bufferedReads++; return rv; } /* Don't inject results before the original is issued to prevent deadlock */ if( GetCurrentHookType( ) != NVMHOOK_POSTISSUE ) { return rv; } currentTime++; if( !request->address.IsTranslated( ) ) { uint64_t row, col, bank, rank, channel, subarray; migratorTranslator->Translate(request, &row, &col, &bank,&rank, &channel, &subarray); request->address.SetTranslatedAddress( row, col, bank, rank, channel, subarray); } //***********************traces start uint64_t pageNo = migratorTranslator->GetAddressKey(request->address); uint64_t channelNo = request->address.GetChannel(); //std::cout<<"request:"<<std::hex<<request->address.GetPhysicalAddress()<<" channel:"<<request->address.GetChannel()<<std::endl; /* if (GetEventQueue()->GetCurrentCycle()%trace_interval==0 ) { for( uint64_t i=0 ; i<channel_num ; i++) { file<<migratorTranslator->migrate_access_times[i]<<" "; origin_file<< migratorTranslator->access_times[i]<<" "; } file<<std::endl; origin_file<<std::endl; }*/ //***********************traces end //this request is issued to access dram memory if( channelNo == promotionChannel && !IsInList(DRAMPageList, pageNo) ) { DRAMPageList.push_back(pageNo); } //get ranking queue num for the request int location = LocateQueue(pageNo); if( location == -1 ) { PageType page = { pageNo, 1, currentTime + LIFE_TIME, channelNo }; //insert the request to queue[0] (LRU) JoinQueue(page); } else { AccessPage(location, pageNo); } Display(); /* See if any migration is possible (i.e., no migration is in progress) */ bool migrationPossible = false; if( !migratorTranslator->Migrating( ) && !migratorTranslator->IsMigrated( request->address ) && channelNo != promotionChannel ) { migrationPossible = true; } else if(migratorTranslator->Migrating( )) { //std::cout<<"\nPossible? ------ No ------ 1\n"<<std::endl; } else if(migratorTranslator->IsMigrated( request->address )) { //std::cout<<"\nPossible? ------ No ------ 2\n"<<std::endl; } else if(channelNo == promotionChannel) { //std::cout<<"\nPossible? ------ No ------ 3\n"<<std::endl; } //std::cout<<"migration possible:"<<migrationPossible<<std::endl; if( migrationPossible ) { //std::cout<<"\n Possible? ---- Yes!\n"<<std::endl; assert( !demoBuffered && !promoBuffered ); //std::cout<<"location is:"<<location<<std::endl; if( location == THRESHOLD_QUEUE && !migratorTranslator->IsMigrated( request->address )) { //std::cout<<"\n Migrate? ---- Yes!\n"<<std::endl; /* * Note: once IssueCommand is called, this hook may receive * a different parent, but fail the NVMTypeMatch check. As a * result we need to save a pointer to the NVMain class we * are issuing requests to. */ NVMObject *savedParent = parent->GetTrampoline( ); //NVMObject *savedParent = main_mem; /* Discard the unused column address. */ uint64_t row, bank, rank, channel, subarray; request->address.GetTranslatedAddress( &row, NULL, &bank, &rank, &channel, &subarray ); uint64_t promoteeAddress = migratorTranslator->ReverseTranslate( row, 0, bank, rank, channel, subarray ); promotee.SetPhysicalAddress( promoteeAddress ); promotee.SetTranslatedAddress( row, 0, bank, rank, channel, subarray ); /* Pick a victim to replace. */ ChooseVictim( migratorTranslator, promotee, demotee ); assert( migratorTranslator->IsMigrated( demotee ) == false ); assert( migratorTranslator->IsMigrated( promotee ) == false ); if( atomic ) { migratorTranslator->StartMigration( request->address, demotee ); migratorTranslator->SetMigrationState( promotee, MQ_MIGRATION_DONE ); migratorTranslator->SetMigrationState( demotee, MQ_MIGRATION_DONE ); } /* Lastly, make sure we can queue the migration requests. */ else if( CheckIssuable( promotee, READ ) && CheckIssuable( demotee, READ ) ) { migratorTranslator->StartMigration( request->address, demotee ); promoRequest = new NVMainRequest( ); demoRequest = new NVMainRequest( ); promoRequest->address = promotee; promoRequest->type = READ; promoRequest->tag = MIG_READ_TAG; promoRequest->burstCount = numCols; demoRequest->address = demotee; demoRequest->type = READ; demoRequest->tag = MIG_READ_TAG; demoRequest->burstCount = numCols; promoRequest->owner = savedParent; demoRequest->owner = savedParent; savedParent->IssueCommand( promoRequest ); savedParent->IssueCommand( demoRequest ); } else { queueWaits++; } } } CheckQueue(); } return rv; }