Develop a C/C++ program that accepts the name of a memory trace file as a command line argument. Use the data to simulate a set associative cache using LRU replacement. Additional command line arguments will be needed to identify the details of the simulated cache. The arguments should appear in the following order: the memory trace input file X, where 2X == the number of direct-mapped sets Y, where 2Y == the number of blocks per set Z, where 2Z == the number of cached words per block Your program (say it's a compiled C program) could be run like this: ./cache data.tra 3 2 4 This would simulate an 8 set associative LRU cache with 4 blocks per set, where each block caches 16 addresses. NOTE… the reason I've chosen to use exponents for arguments is to ensure we have powers of 2 for everything. Trace File The trace file is line based with each line containing a memory address requested, in hex. Please note this data is real, so the addresses are larger than 32-bits. In languages like C/C++, you should store these values in size_t or uint64_t variables. Program output When finished analyzing the trace data, your program should print the hit ratio (the total number of already cached accesses / the total access count). The output should be formatted EXACTLY as below with only the numbers varying. Example proper output would be (I made up the numbers): hits: 1234/234567 Test Files Included is a Zip file of memory access traces for four programs running for a brief period: ls.tra: 1132300 memory accesses while listing all files recursively from a location on my drive grep.tra: 1183871 memory accesses while grepping for a pattern in files in my directory gpp.tra: 2219618 memory accesses while compiling my solution to this assignment fib100.tra: 2907236 memory accesses while running a program to recursively find the 100th Fibonacci number Test File Results For each of the 4 test files, here's what my solution prints out for various X, Y, Z arguments, each chosen to result in the capacity to cache 64K words of data… Direct Mapped 10 0 6 Set Associative 6 4 6 Fully Associative 0 10 6 ls.tra hits: 1118693 / 1132300 hits: 1124845 / 1132300 hits: 1124872 / 1132300 grep.tra hits: 1169929 / 1183871 hits: 1175976 / 1183871 hits: 1175998 / 1183871 gpp.tra hits: 1427048 / 1444506 hits: 1435975 / 1444506 hits: 1436013 / 1444506 fib100.tra hits: 2795730 / 2907236 hits: 2890936 / 2907236 hits: 2890950 / 2907236 Notice as you go from left to right in the above table, the hits improve. When you run your simulations, please notice the relative speed performance compared to the hits gain This code can be very straightforward. While I have the benefit of experience, your programs should also be relatively short. If they start pushing two to three times this size come see me for help. Here is some pseudo code that can be implemented in the code:setPow = atoi(argv[2]) blockPow = atoi(argv[3]) wordPow = atoi(argv[4]) // Do some argument checking first SETS = 1<<setPow // Get number of sets BPS = 1<<blockPow // Get number of block per set WPB = 1<<wordPow // Get number of words per block cache set[SETS] set blocks[BPS]; typedef struct{ bool dirty = false; uint64_t Tag; unsigned int LRU = 0; } block; uint64_t address =?; addr >>= wordPow; setBits = addr & ~(~0U << setPow); tag = addr >> setPow;
Develop a C/C++ program that accepts the name of a memory trace file as a command line argument. Use the data to simulate a set associative cache using LRU replacement. Additional command line arguments will be needed to identify the details of the simulated cache. The arguments should appear in the following order:
-
the memory trace input file
-
X, where 2X == the number of direct-mapped sets
-
Y, where 2Y == the number of blocks per set
-
Z, where 2Z == the number of cached words per block
Your program (say it's a compiled C program) could be run like this:
./cache data.tra 3 2 4
This would simulate an 8 set associative LRU cache with 4 blocks per set, where each block caches 16 addresses. NOTE… the reason I've chosen to use exponents for arguments is to ensure we have powers of 2 for everything.
Trace File
The trace file is line based with each line containing a memory address requested, in hex. Please note this data is real, so the addresses are larger than 32-bits. In languages like C/C++, you should store these values in size_t or uint64_t variables.
Program output
When finished analyzing the trace data, your program should print the hit ratio (the total number of already cached accesses / the total access count). The output should be formatted EXACTLY as below with only the numbers varying. Example proper output would be (I made up the numbers):
hits: 1234/234567 |
Test Files
Included is a Zip file of memory access traces for four programs running for a brief period:
-
ls.tra: 1132300 memory accesses while listing all files recursively from a location on my drive
-
grep.tra: 1183871 memory accesses while grepping for a pattern in files in my directory
-
gpp.tra: 2219618 memory accesses while compiling my solution to this assignment
-
fib100.tra: 2907236 memory accesses while running a program to recursively find the 100th Fibonacci number
Test File Results
For each of the 4 test files, here's what my solution prints out for various X, Y, Z arguments, each chosen to result in the capacity to cache 64K words of data…
Direct Mapped 10 0 6 |
Set Associative 6 4 6 |
Fully Associative 0 10 6 |
|
ls.tra |
hits: 1118693 / 1132300 |
hits: 1124845 / 1132300 |
hits: 1124872 / 1132300 |
grep.tra |
hits: 1169929 / 1183871 |
hits: 1175976 / 1183871 |
hits: 1175998 / 1183871 |
gpp.tra |
hits: 1427048 / 1444506 |
hits: 1435975 / 1444506 |
hits: 1436013 / 1444506 |
fib100.tra |
hits: 2795730 / 2907236 |
hits: 2890936 / 2907236 |
hits: 2890950 / 2907236 |
Notice as you go from left to right in the above table, the hits improve. When you run your simulations, please notice the relative speed performance compared to the hits gain
This code can be very straightforward. While I have the benefit of experience, your programs should also be relatively short. If they start pushing two to three times this size come see me for help.
Here is some pseudo code that can be implemented in the code:
setPow = atoi(argv[2]) blockPow = atoi(argv[3]) wordPow = atoi(argv[4]) // Do some argument checking first SETS = 1<<setPow // Get number of sets BPS = 1<<blockPow // Get number of block per set WPB = 1<<wordPow // Get number of words per block cache set[SETS] set blocks[BPS]; typedef struct{ bool dirty = false; uint64_t Tag; unsigned int LRU = 0; } block; uint64_t address =?; addr >>= wordPow; setBits = addr & ~(~0U << setPow); tag = addr >> setPow;
Step by step
Solved in 2 steps