The Dram represents the main memory of the machine as well as the interactions (primarily latency) between main memory and the processor.
There are two models provided. The chunk (default) model as well as a basic row-buffer model. An abstract class is provided that allows itself to be inherited from in order to create new memory models.
The chunk model is referred to in the simulator as "dram_default". Latency to main memory is determined by the sum of first chunk latency + interchunk latency for each additional chunk.
int num_chunks = (request_size + (bus_width - 1)) / bus_width; latency = first_chunk_latency + (interchunk_latency * (num_chunks-1));
The default values are as follows:
bus_width: 4 bytes (previous versions used 8 bytes here) first_chunk_latency: 300 cycles interchunk_latency: 2 cycles configuration string: -mem:config chunk:4:300:2
Basic Row-Buffer Model
The Basic Row-Buffer model is referred to in the simulator as "dram_basic". Main memory is divided into banks that can service requests in parallel. Banks retain a row-hit buffer that contains the most recently accessed row in order to exploit locality.
Each row-hit buffer is in one of two states, closed or precharged.
- If closed, an access will cause data to be loaded in the row-hit buffer and then a precharge occurs - changing the state to precharged with the appropriate data and incurring delay for loading to the row (closed) and precharging (pre).
- If precharged, an access that hits into the row will only incur a precharging delay (pre). If it misses into the row, we must evict the current data (conflict), load to the row (closed) and precharge (pre) - generating the maximum delay.
Each request must travel from the processor to main memory (to_dram) and the size of the request requires transfer time (from_dram, based on number of transfers -> size/bus_width).
There is no default value, but we'll describe a typical value:
configuration string: -mem:config basic:4:6:12:80:80:80:8:2048 configuration definition: name:bus_width:to_dram:from_dram:pre:closed:conflict:number_of_banks:row_buffer_size bus_width: 4 bytes, the default transfer size from main memory to the processor. Larger requests simply take up more transfer time back to the processor to_dram: 6 cycles, time for a request to get from the processor to main memory from_dram: 12 cycles, time for bus_width bytes to be transferred from main memory to the processor pre: 80 cycles (first 80), time required for precharging to occur closed: 80 cycles (second 80), time required to activate a closed row-buffer conflict: 80 cycles (third 80), time required to flush a row-buffer number_of_banks: 8 banks, divides main memory into 8 sections row_buffer_size: 2048 bytes, size of the row-hit buffer - the amount of data brought into the row-hit buffer upon loading with new data.
Each core has access to the main memory model via the pointer: main_mem.
dram_t is designed as follows
- virtual unsigned int mem_access_latency(md_addr_t addr, int size, tick_t when, int context_id)=0;
- This is the memory access method, it takes the address of the request, the size (in bytes), the time the request was made and the id of the context that made the request.
- This must be provided in a child class. This is where all the appropriate work is done by each model.
- virtual void reset( ); Is called after fast forwarding to reset internal data if needed
- If not provided for in a child class, this will simply do nothing when called.
Adding New Models
Aside from adding a new class that inherits from dram_t and providing the appropriate functions, an entry into dram_parser (dram.c) must be made.
dram_t * dram_parser(std::string config)
This takes the configuration string and parses it. At the point "//ADD NEW TYPES HERE!", the configuration string has been parsed into the vector<string> "args" with the requested model stored in the string "type". Add a condition to match "type" with the name of your model and then return a pointer to a newly allocated memory model (deallocation is handled in sim_uninit).
- machine.h (for type definitions tick_t and md_addr_t)