tags:

views:

160

answers:

3

Is there a way in c++ to quickly invalidate the L2 cache of a processor other than iterating through a large fake array?

+1  A: 

I'm going to assume this is for performance testing and you want to eliminate cache effects between runs.

In that case, what you'd need to know to do this efficiently is:

  1. The allocation size of the L2 cache
  2. How many allocations there are in the L2 cache

Then it's basically a matter of touching memory allocation_size bytes away from each other until you've flushed the cache entirely.

Context switching also often invalidates the cache - it might be faster to wait for a millisecond and if the OS swaps you in and out, it'll likely end up clearing the cache.

Anon.
That's the portable way to do it. There is likely a way to escape to assembly and make it happen there. Some processors may even have a single instruction that does it.
Omnifarious
this is for very high resolution timing with run lengths of about 50 nanoseconds, which is why i'd like to use the fastest method possible
Mark
If you can get into kernel mode, you can issue a WBINVD, which will cause all internal caches to be flushed. Just be aware that it the instruction was designed back when caches were tiny, and so it takes a (relatively) long time to complete and in general isn't recommended. (see http://linux.derkeiler.com/Mailing-Lists/Kernel/2009-07/msg09421.html)
Anon.
I'm taking this answer for the last comment as iterating through by cache lines is what I was already doing before.
Mark
A: 

You want to use a memory fence. in vc++:

void SThreadUtil::synchronizeCache()
{
    _mm_mfence();
}

sorry. For flushing it should be _mm_clflush

Charles Eli Cheese
Are you sure that will invalidate the cache? Don't memory fences just guarantee an ordering between when memory operations are seen on the bus to main memory?
Omnifarious
_mm_cflush takes an argument though, so the OP will have to guess about what things may be in cache that will interfere and then make sure to flush them all.
Omnifarious
It looks like _mm_clflush will only flush one cache line at a time -http://msdn.microsoft.com/en-us/library/ba08y07y.aspx
Mark
+1  A: 

Another possible answer is to make sure a completely different section of memory is used each time the thing that is sensitive to cache contents is run. Then none of those bits of memory will be in cache and, effectively, the cache will be flushed.

Of course, this might not be a very easily managed solution for the instruction cache, only for the data cache, and even then handling the stack will be tricky.

And I can't think of a way for this approach to work reliably for the TLB cache either, if you care about that.

And another problem this approach has is that there may still be dirty cache lines and a later run of the code will incur the cost of flushing them to main memory.

Omnifarious