Stream Prefetcher

一些参数

static const uint32_t MaxContexts = 64; // Creates per-core stream tables for upto 64 processor cores
uint32_t tableSize;       // Number of entries in a stream table
const bool useMasterId;   // Use the master-id to train the streams
uint32_t degree;          // Determines the number of prefetch reuquests to be issued at a time
uint32_t distance;        // Determines the prefetch distance

一些定义

// Direction of stream for each stream entry in the stream table
enum StreamDirection{
        ASCENDING = 1,                      // For example - A, A+1, A+2
        DESCENDING = -1,                    // For example - A, A-1, A-2
        INVALID = 0
};
// Status of a stream entry in the stream table.
enum StreamStatus{
	INV       = 0,
	TRAINING  = 1,  // Stream training is not over yet. Once trained will move to MONITOR status
	MONITOR   = 2  // Monitor and Request: Stream entry ready for issuing prefetch requests
};
class StreamTableEntry {
  public:
	int  LRU_index;
	Addr allocAddr;                     // Address that initiated the stream training
	Addr startAddr;                     // First address of a stream
	Addr endAddr;                       // Last address of a stream
	StreamDirection trainedDirection;   // Direction of trained stream (Ascending or Descending)
	StreamStatus    status;             // Status of the stream entry
	StreamDirection trendDirection[2];  // Stores the last two stream directions of an entry
};

核心函数

1. Monitor状态

switch (table[i]->status) {
case MONITOR:
	if(table[i]->trainedDirection == ASCENDING) {
		// Ascending order
		if((table[i]->startAddr < blk_addr ) && ( table[i]->endAddr > blk_addr)) {
			// Hit to a stream, which is monitored. Issue prefetch requests based on the degree and the direction
			for (uint8_t d = 1; d <= degree; d++) {
				Addr pf_addr = table[i]->endAddr + blkSize * d;
				addresses.push_back(AddrPriority(pf_addr,0));
				DPRINTF(HWPrefetch, "Queuing prefetch to %#x.\n", pf_addr);
			}
			if((table[i]->endAddr + blkSize * degree) - table[i]->startAddr <= distance) {
				table[i]->endAddr   = table[i]->endAddr + blkSize * degree;
			} else {
				table[i]->startAddr = table[i]->startAddr + blkSize * degree;
				table[i]->endAddr   = table[i]->endAddr   + blkSize * degree;
			}
			break;
		}
	} else if(table[i]->trainedDirection == DESCENDING) {
		// 同上
	} else{
		assert(0);
	}
	break;

2. Training状态

case TRAINING:
if ((abs(table[i]->allocAddr - blk_addr) <= (distance/2) * blkSize) ){
	// Check whether the address is in +/- of distance
	if(table[i]->trendDirection[0] == INVALID){
		table[i]->trendDirection[0] = (blk_addr - table[i]->allocAddr > 0) ? ASCENDING : DESCENDING;
	} else {
		assert(table[i]->trendDirection[1] == INVALID);
		table[i]->trendDirection[1] = (blk_addr - table[i]->allocAddr > 0) ? ASCENDING : DESCENDING;
		if(table[i]->trendDirection[0] == table[i]->trendDirection[1]) {
			table[i]->trainedDirection = table[i]->trendDirection[0];
			table[i]->startAddr = table[i]->allocAddr;
			if(table[i]->trainedDirection != INVALID){
				// Based on the trainedDirection (+1:Ascending, -1:Descending) update the end address of a stream
				table[i]->endAddr = blk_addr + (table[i]->trainedDirection) * blkSize * degree;
			}
			// Entry is ready for issuing prefetch requests
			table[i]->status = MONITOR;
		} else {
			resetEntry(table[i]);
		}
	}
	break;
}
break;

3. 没有匹配的Stream

int entry_id;
if(HIT_index!=tableSize) {  //hit
	entry_id = HIT_index;
} else if (INVALID_index!=tableSize) {
	//Existence of invalid streams
	assert(table[INVALID_index]->status == INV);
	table[INVALID_index]->status = TRAINING;
	table[INVALID_index]->allocAddr = blk_addr;
	entry_id = INVALID_index;
} else {
	//Replace the LRU stream-entry
	assert(table[LRU_index]->status!=INV);
	resetEntry(table[LRU_index]);
	table[LRU_index]->status = TRAINING;
	table[LRU_index]->allocAddr = blk_addr;
	entry_id = LRU_index;
}
    ```

# References
[gem5-with-DPC-2-prefetcher/stream.hh at master · hfsken/gem5-with-DPC-2-prefetcher · GitHub](https://github.com/hfsken/gem5-with-DPC-2-prefetcher/blob/master/src/mem/cache/prefetch/stream.hh)