示例#1
0
ncycles_t RowModel::Write( NVMainRequest *request, NVMDataBlock& /*oldData*/ ) 
{
    NVMAddress address = request->address;

    /*
     *  The default life map is an stl map< uint64_t, uint64_t >. 
     *  You may map row and col to this map_key however you want.
     *  It is up to you to ensure there are no collisions here.
     */
    uint64_t row;
    ncycles_t rv = 0;

    /*
     *  For our simple row model, we just set the key equal to the row.
     */
    address.GetTranslatedAddress( &row, NULL, NULL, NULL, NULL, NULL );
    
    /*
     *  If using the default life map, we can call the DecrementLife
     *  function which will check if the map_key already exists. If so,
     *  the life value is decremented (write count incremented). Otherwise 
     *  the map_key is inserted with a write count of 1.
     */
    if( !DecrementLife( row ) )
        rv = -1;

    return rv;
}
示例#2
0
ncycles_t WordModel::Write( NVMainRequest *request, NVMDataBlock& /*oldData*/ ) 
{
    NVMAddress address = request->address;

    /*
     *  The default life map is an stl map< uint64_t, uint64_t >. 
     *  You may map row and col to this map_key however you want.
     *  It is up to you to ensure there are no collisions here.
     */
    uint64_t row;
    uint64_t col;
    ncycles_t rv = 0;

    /*
     *  For our simple row model, we just set the key equal to the row.
     */
    address.GetTranslatedAddress( &row, &col, NULL, NULL, NULL, NULL );

    /*
     *  If using the default life map, we can call the DecrementLife
     *  function which will check if the map_key already exists. If so,
     *  the life value is decremented (write count incremented). Otherwise 
     *  the map_key is inserted with a write count of 1.
     */
    uint64_t wordkey;
    uint64_t rowSize;
    uint64_t wordSize;
    uint64_t partitionCount;

    wordSize = p->BusWidth;
    wordSize *= p->tBURST * p->RATE;
    wordSize /= 8;

    rowSize = p->COLS * wordSize;

    /*
     *  Think of each row being partitioned into 64-bit divisions (or
     *  whatever the Bus Width is). Each row has rowSize / wordSize
     *  paritions. For the key we will use:
     *
     *  row * number of partitions + partition in this row
     */
    partitionCount = rowSize / wordSize;

    wordkey = row * partitionCount + col;

    if( !DecrementLife( wordkey ) )
        rv = -1;

    return rv;
}
示例#3
0
/*
 *  Calculates a unique key for each possible unit of memory that can be
 *  migrated. In this case, we are migrating single rows of a bank.
 */
uint64_t MQMigrator::GetAddressKey( NVMAddress& address )
{
    uint64_t row, bank, rank, subarray, channel;
    address.GetTranslatedAddress( &row, NULL, &bank, &rank, &channel, &subarray );

    /* 
     * We will migrate entire memory pages, therefore only the column is
     * irrelevant.
     */
    return (row * numBanks * numRanks * numSubarrays * numChannels 
            + bank * numRanks * numSubarrays * numChannels
            + rank * numSubarrays * numChannels
            + subarray * numChannels
            + channel);
}
示例#4
0
uint64_t MultiQueueMigrator::GetPageNumber( MQMigrator *at, NVMAddress address )
{
	uint64_t pageNum = at->GetAddressKey(address);

	if(at->IsMigrated(address))
	{
		uint64_t channel;
		address.GetTranslatedAddress(NULL, NULL, NULL, NULL, &channel, NULL);
		
		uint64_t newChannel = at->GetNewChannel(address);
		pageNum = pageNum - channel + newChannel;
	}
	
	return pageNum;
}
示例#5
0
ncycles_t ByteModel::Write( NVMainRequest *request, NVMDataBlock& oldData ) 
{
    NVMDataBlock& newData = request->data;
    NVMAddress address = request->address;

    /*
     *  The default life map is an stl map< uint64_t, uint64_t >. 
     *  You may map row and col to this map_key however you want.
     *  It is up to you to ensure there are no collisions here.
     */
    uint64_t row;
    uint64_t col;
    ncycles_t rv = 0;

    /*
     *  For our simple row model, we just set the key equal to the row.
     */
    address.GetTranslatedAddress( &row, &col, NULL, NULL, NULL, NULL );
    
    /*
     *  If using the default life map, we can call the DecrementLife
     *  function which will check if the map_key already exists. If so,
     *  the life value is decremented (write count incremented). Otherwise 
     *  the map_key is inserted with a write count of 1.
     */
    uint64_t wordkey;
    uint64_t rowSize;
    uint64_t wordSize;
    uint64_t partitionCount;

    /* 
     * wordSize is the size of a word written to memory, usually a cacheline. 
     * This size is in bytes 
     */
    wordSize = p->BusWidth;
    wordSize *= p->tBURST * p->RATE;
    wordSize /= 8;

    /* Size of a row in bytes */
    rowSize = p->COLS * wordSize;

    /* Check each byte to see if it was modified */
    for( int i = (int)wordSize - 1; i >= 0; --i )
    {
        uint8_t oldByte, newByte;

        oldByte = oldData.GetByte( i );
        newByte = newData.GetByte( i );

        if( oldByte == newByte ) 
            continue;

        /*
         *  Think of each row being partitioned into 8-bit divisions. Each 
         *  row has rowSize / 8 paritions. For the key we will use:
         *
         *  row * number of partitions + partition in this row
         */
        partitionCount = ( rowSize / 8 );

        wordkey = row * partitionCount + col * wordSize + i;
      
        if( !DecrementLife( wordkey ) )
            rv = -1;  
    }

    return rv;
}