DFPC NVM源碼增添解析

源碼增添分爲三個部分

部分一

NVMain::NVMain( )
{
    config = NULL;
    translator = NULL;
    memoryControllers = NULL;
    channelConfig = NULL;
    syncValue = 0.0f;
    preTracer = NULL;

    totalReadRequests = 0;
    totalWriteRequests = 0;

    prefetcher = NULL;
    successfulPrefetches = 0;
    unsuccessfulPrefetches = 0;
	//這下面這四個是多出來的
	num_read_requests = 0;
	sum_read_latency = 0;
	num_write_requests = 0;
	sum_write_latency = 0;
}

第二部分

bool NVMain::RequestComplete( NVMainRequest *request )
{
    bool rv = false;

	//下面這兩個是增加的,用於統計
	if(request->type == READ)
    {
        num_read_requests ++;
	    sum_read_latency += (request->completionCycle - request->arrivalCycle);
    }
    else if(request->type == WRITE)
    {
        num_write_requests ++;
	    sum_write_latency += (request->completionCycle - request->arrivalCycle);
    }
	
	
    if( request->owner == this )
    {
        if( request->isPrefetch )
        {
            //std::cout << "Placing 0x" << std::hex << request->address.GetPhysicalAddress( )
            //          << std::dec << " into prefetch buffer (cur size: " << prefetchBuffer.size( )
            //          << ")." << std::endl;

            /* Place in prefetch buffer. */
            if( prefetchBuffer.size() >= p->PrefetchBufferSize )
            {
                unsuccessfulPrefetches++;
                //std::cout << "Prefetch buffer is full. Removing oldest prefetch: 0x" << std::hex
                //          << prefetchBuffer.front()->address.GetPhysicalAddress() << std::dec
                //          << std::endl;

                delete prefetchBuffer.front();
                prefetchBuffer.pop_front();
            }

            prefetchBuffer.push_back( request );
            rv = true;
        }
        else
        {
            delete request;
            rv = true;
        }
    }
    else
    {
        rv = GetParent( )->RequestComplete( request );
    }

    /* This is used in the main memory system when a DRAMCache is present.
     * DRAMCache misses need to issue main memory requests than might not
     * be issuable at that time. Try to issue these here. */
    if( !pendingMemoryRequests.empty() ){
       NVMainRequest *staleMemReq = pendingMemoryRequests.front();
        if( IsIssuable(staleMemReq, NULL) ) {
            IssueCommand( staleMemReq );
            pendingMemoryRequests.pop();
        }
    }

    return rv;
}

第三部分nvmain的cycle

1.主頻:主頻也叫時鐘頻率,單位是MHz,用來表示CPU的運算速度。主頻由外頻和倍頻決定,其計算公式爲 主頻=外頻倍頻。外頻就是系統總線的工作頻率;而倍頻則是指CPU外頻與主頻相差的倍數。如Intel Pentium4 3.06GHz處理器的外頻爲133,倍頻23,則主頻=13323=3.06Ghz
2.外頻:外頻是CPU的基準頻率,單位也是MHz。外頻是CPU與主板之間同步運行的速度,而且目前的絕大部分電腦系統中,外頻也是內存與主板之間的同步運行的速度,在這種方式下,可以理解爲CPU的外頻直接與內存相連通,實現兩者間的同步運行狀態。

應該是計算倍頻的倒數,如果大於一就減一(怎麼可能大於1呢,總線比cpu快就離譜啊)
如果大於1,還要給每個內存控制器添加1ns的事務象徵性搞一下

void NVMain::Cycle( ncycle_t steps )
{
    assert( !p->EventDriven );
    /*
     *  Previous errors can prevent config from being set. Likewise, if the first memoryController is
     *  NULL, so are all the others, so return here instead of seg faulting.
     */
    if( !config || !memoryControllers )
      return;

    /* Sync the memory clock with the cpu clock. */
    double cpuFreq = static_cast<double>(p->CPUFreq);
    double busFreq = static_cast<double>(p->CLK);

    syncValue += static_cast<double>( busFreq / cpuFreq );

    if( syncValue >= 1.0f )
    {
        syncValue -= 1.0f;
    }
    else
    {
        return;
    }

    for( unsigned int i = 0; i < numChannels; i++ )
    {
        memoryControllers[i]->Cycle( 1 );
    }

    GetEventQueue()->Loop( steps );
}

第四部分

void NVMain::CalculateStats( )
{
//多了兩個打印
    std::cout<<"DRAM read number: "<< num_read_requests << "\t read latency: " <<1.0*sum_read_latency/num_read_requests << std::endl;
    std::cout<<"DRAM write number: "<< num_write_requests << "\t write latency: " <<1.0*sum_write_latency/num_write_requests << std::endl;
    for( unsigned int i = 0; i < numChannels; i++ )
        memoryControllers[i]->CalculateStats( );
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章