Hi
I want to write a small application to estimate the size of my L1 data and L2 caches.
I don't want to use OS specific calls, such as Windows' GetLogicalProcessorInformation or on Linux looking in /proc/cpuinfo or dmesg etc
The logic behind my first attempt is quite simple - write to increasingly larger arrays, calculating how long it takes to do this, and you should notice an increase in access time at the 2 cache boundaries.
So here's my code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
#include <iostream>
#include <time.h>
#include <cstdio>
clock_t whack_cache(const int sz)
{
char* buf = new char[sz];
clock_t start = clock();
for (int64_t i = 0; i < 64 * 1024 * 1024; i++)
++buf[(i * 64) % sz]; // writing in increments hopefully means we write to a new cache-line every time
clock_t elapsed = clock() - start;
delete [] buf;
return elapsed;
}
int main()
{
std::cout << "writing timing results to \"results.csv\"" << std::endl;
FILE* f = fopen("results.csv", "w");
if (!f)
return 1;
for (int sz = 1024; sz <= 16 * 1024 * 1024; sz <<= 1)
{
fprintf(f, "%d, %lu\n", sz / 1024, whack_cache(sz));
std::cout << ".";
fflush(stdout);
}
fclose(f);
std::cout << "done" << std::endl;
return 0;
}
| |
It produces the following output:
1, 1013997
2, 1012313
4, 1008917
8, 1004319
16, 1003130
32, 1002857
64, 1001270
128, 994797
256, 994616
512, 994171
1024, 995780
2048, 1059103
4096, 1975768
8192, 2142419
16384, 2146428 |
As you can see, there is a noticeable increase in clock-ticks between 2MB and 4MB. As it turns out, I have a 3MB L2 cache, so this logic is working.
However, there is nothing to show where the L1 data cache boundary is. Running cpu-x (I'm on a mac), I am told I have 2 x 32K L1 data caches (1 per core, Core 2 Duo processor).
So my questions are:
1. Why am I not getting results that show an increase at 64K
2. How can I estimate the size of my L1 data cache?
3. How do applications like CPU-X and CPU-Z etc calculate the cache sizes?
Many thanks in advance
Steve