CSCI 2330
Introduction to Systems

Bowdoin College
Spring 2017
Instructor: Sean Barker

Project 5 - Make Some Cache

This project may be completed either individually or in groups of 2. If you work in a group, you should be coding at the same time in front of one machine (this is sometimes called 'pair programming'). Take turns driving.

This project will help you understand the different types of caches designs and the impact that cache memories can have on the performance of your programs. To do so, you will write a C program simulating the behavior of a cache memory on real-world memory usage traces.

Start by reading through the entire project description!

Project Dates

AssignedWednesday, April 19.
DueThursday, April 27.

Project Overview

Your cache simulator will simulate an arbitrary cache memory, as defined by the usual three values S (the number of sets), E (the number of lines per set), and B (the size of a data block). Your program will simulate the behavior of the specified cache on a trace file, which consists of a series of memory accesses that you will replay in simulation. The output of your simulator will be three values: the number of cache hits, the number of cache misses, and the number of block evictions performed.

To help you test your program, you have been provided with a reference implementation, as well as a driver program that will automatically test your simulator by comparing its results against the reference simulator. Details on the trace files and the reference simulator are provided below.

Reference Trace Files

The traces subdirectory of your project directory contains a collection of reference trace files that will be used to evaluate the correctness of your cache simulator. These trace files describe a series of memory accesses and are generated by valgrind. The traces have the following format:

I 0400d7d4,8
 M 0421c7f0,4
 L 04f6b868,8
 S 7ff0005c8,8

Each line denotes one or two memory accesses. The general format of each line is

[space]operation address,size

The operation field denotes the type of memory access: "I" denotes an instruction load, "L" a data load, "S" a data store, and "M" a data modify (i.e., a data load followed by a data store). There is never a space before each "I", while there is always a space before each "M", "L", or "S". The address field specifies a 64-bit hex memory address. The size field specifies the number of bytes accessed by the operation.

In addition to the included traces, you can use valgrind to generate your own memory traces in this format, like so:

$ valgrind --log-fd=1 --tool=lackey -v --trace-mem=yes ls -l

The above example will run the program ls -l and dump a trace of its memory accesses to stdout. To save the output in a file, just redirect to a file by appending something like > ls.trace to the end of the valgrind command as we've seen in the past.

Cache Simulator

You have been provided with the compiled executable of a reference cache simulator called cachesim-ref to help you in testing your program. Just like the simulator you will write, the reference simulator outputs the total number of hits, misses, and evictions when running a given valgrind trace through the specified cache.

The reference simulator takes the following command-line arguments:

For example, here is an example run of the reference simulator:

$ ./cachesim-ref -s 4 -E 1 -b 4 -t traces/t2.trace
hits:4 misses:5 evictions:3

Running the same with the addition of the -v flag will print information about each memory access in the trace:

$ ./cachesim-ref -v -s 4 -E 1 -b 4 -t traces/t2.trace
L 10,1 miss 
M 20,1 miss hit 
L 22,1 hit 
S 18,1 hit 
L 110,1 miss eviction 
L 210,1 miss eviction 
M 12,1 miss eviction hit 
hits:4 misses:5 evictions:3

Your job is to complete your own cache simulator such that it takes the same command-line arguments as the reference simulator and produces identical output. You should write your simulator in cachesim.c. Note that this file is almost completely empty -- you'll need to write your simulator from scratch.

Cache Specification

In addition to following the reference implementation output format, you must adhere to the following specifications while designing your cache simulator. Read each of these points carefully, as each one of them has the potential to completely change your cache's behavior if ignored.

Included Files

Your project files contained in proj5 consist of the following:

To test your cache simulator against all of the included trace files and output an autograded correctness score, just execute the test-cachesim program:

$ ./test-cachesim 
                        Your simulator     Reference simulator
Points (s,E,b)    Hits  Misses  Evicts    Hits  Misses  Evicts
     3 (1,1,1)       9       8       6       9       8       6  traces/t1.trace
     3 (4,2,4)       4       5       2       4       5       2  traces/t2.trace
     3 (2,1,4)       2       3       1       2       3       1  traces/t3.trace
     3 (2,1,3)     167      71      67     167      71      67  traces/t4.trace
     3 (2,2,3)     201      37      29     201      37      29  traces/t4.trace
     3 (2,4,3)     212      26      10     212      26      10  traces/t4.trace
     3 (5,1,5)     231       7       0     231       7       0  traces/t4.trace
     6 (5,1,5)  265189   21775   21743  265189   21775   21743  traces/t5.trace

Simulator summary: scored 27 of 27 points

General Advice

Here are some general tips for working on the cache simulator:

Useful C Functions

You will want to make use of the C standard library while working on your simulator. Here are some particular functions that you may wish to use (but feel free to expand beyond this list):


You are responsible for completing the contents of the cachesim.c file. You should not modify any other file (e.g., you should not add any code to cache.c or cache.h).

As usual, your final submission will consist of your committed cachesim.c file at the time of the due date.


You will be evaluated both on the correctness of your cache simulator (as determined by test-cachesim) as well as the style and overall quality of your program (as determined by me).

Note: for full credit, your program must compile without any warnings on the class server!

You should follow all standard and sensible style guidelines, such as using good variable names, commenting, using consistent indentation, breaking up functionality into small, well-defined functions, etc. While you do not have to adhere to any particular set of conventions (e.g., where to put parentheses), you SHOULD be consistent with whatever conventions you choose.

Please ask if you have any questions about what contitutes good style or what is expected!