How to clear the processor cache in Linux from program C?

I am writing a C program in which I need to clear my memory. I would like to know if there is any UNIX system command to clear the processor cache.

This is a requirement for my project, which includes calculating the time spent on my logic.

I read about the cacheflush(char *s, int a, int b) function cacheflush(char *s, int a, int b) , but I'm not sure if it will be suitable and what to pass in the parameters.

+6
source share
4 answers

Note:

At this (very, very low) level of "Linux"! = "Unix"

+6
source

If you are writing a user-mode program (not in kernel mode), and if it is single-threaded, then there really is no reason for you to ever try to flush your cache first. Your user mode program may just forget that it exists; this is just to speed up the execution of your program, and the OS controls it through the MMU processor.

There are only a few reasons why I might think that you really can reset the cache from your user mode:

  • Your application is designed to work on a symmetric multiprocessor system or has data transactions with external equipment)
  • You just check your cache for some kind of performance test (in this case, you probably should write your test to work in kernel mode, possibly as a driver).

Anyway, if you are using Linux ...

 #include <asm/cachectl.h> int cacheflush(char *addr, int nbytes, int cache); 

This assumes that you have the memory block that you just wrote, and you want it to exit the cache back to main memory. A block starts with addr and lasts nbytes, and it is in one of two caches (or both):

  ICACHE Flush the instruction cache. DCACHE Write back to memory and invalidate the affected valid cache lines. BCACHE Same as (ICACHE|DCACHE). 

Usually you only need to clear DCACHE, because when you write data to "memory" (that is, to the cache), it is usually data, not instructions.

If you want to reset the “whole cache” for some strange testing reason, you can malloc () a large block, which, as you know, is larger than your processor’s cache (shoot, make it 8 times bigger!), Write any old one trash into it and just clear this whole block.

See also: How to perform cache operations in C ++?

+2
source

OK, sorry for my first answer. Later I read your subsequent comments under your question, so now I understand that you want to clear INSTRUCTION CACHE in order to load your program (or parts of it) from the cache, so that while checking its performance you also tested its initial load time from main memory in command cache. Do you also need to clear any data that your code will use in main memory so that the data and code are fresh?

First of all, I would like to mention that main memory itself is also a form of cache, and your hard drive (either a program on disk or a swap space on disk) is the lowest and slowest place for your program instructions to occur. However, when you first start the procedure for the first time, if it is not already loaded into the main memory from the disk due to the fact that it is next to another code that has already been executed, then its CPU commands from the disk must be loaded first. This takes about or more longer than loading it from main memory into the cache. Then, as soon as it is loaded into the main memory, it takes about an order of magnitude more time to load from the main memory to the cache than it does to load from the cache into the processor instruction collector. Therefore, if you want to test the performance of your cold start code, you need to decide what a cold start means ... pulling it out of the disk or pulling it out of main memory. I don’t know any command to “flush” instructions / data from the main memory in order to swap, so flushing to the main memory is about the same as you can (what I know), but keep in mind that your test results may still vary from the first run (when he can pull it out of the disk) into subsequent runs, even if you dumped the command cache.

Now, how could you clear the command cache to make sure that their own code has been dumped into main memory?

If I needed it (very strange, in my opinion), I would probably start by looking for the length and approximate placement of my functions in memory. Since I use Linux, I would issue the command "objdump -d {myprogram}> myprogram.dump.txt", then I would open the myprogram.dump.txt file in the editor and search for the functions that I want to reset and find out how long they subtract your final address from your starting address using a hexadecimal calculator. I would write down the sizes of each of them. Later I added cacheflush () calls in my code, giving it the address of each function that I want to reset as "addr", and the length that I found as "nbytes", and ICACHE. Just for safety, I probably lost a little weight and added about 10% to the size, just in case I make a few settings in the code and forget to adjust nbytes. I would make a call to cacheflush (), like this for every function I want to disable. Then, if I also need to wash the data, if they use global / static data, I can also clear it (DCACHE), but if it adds or accumulates data, there really is nothing realistic that I can (or should) do for a flash that from cache. Trying to do this would be an exercise in stupidity, because it would create a condition that would never or very rarely exist under normal execution. Assuming you are using Linux ...

 #include <asm/cachectl.h> int cacheflush(char *addr, int nbytes, int cache); ...where cache is one of: ICACHE Flush the instruction cache. DCACHE Write back to memory and invalidate the affected valid cache lines. BCACHE Same as (ICACHE|DCACHE). 

By the way, is this homework for the class?

+1
source

Here's how Intel suggests flushing the cache:

 mem_flush(const void *p, unsigned int allocation_size){ const size_t cache_line = 64; const char *cp = (const char *)p; size_t i = 0; if (p == NULL || allocation_size <= 0) return; for (i = 0; i < allocation_size; i += cache_line) { asm volatile("clflush (%0)\n\t" : : "r"(&cp[i]) : "memory"); } asm volatile("sfence\n\t" : : : "memory"); } 
+1
source

Source: https://habr.com/ru/post/893062/


All Articles