如何从C程序中刷新Linux中的CPU缓存?

Ros*_*Eck 9 c unix linux caching flush

我正在写一个C程序,我需要冲洗我的记忆.我想知道是否有任何UNIX系统命令来刷新CPU缓存.

这是我的项目的一项要求,它涉及计算我的逻辑所需的时间.

我已经阅读了有关该cacheflush(char *s, int a, int b)功能的内容,但我不确定它是否合适以及在参数中传递什么.

pau*_*sm4 9

  1. 我认为你的意思是"CPU缓存",而不是内存缓存

  2. 上面的链接很好:建议"通过CPU写入大量数据" 不是 Windows特定的

  3. 这是同一主题的另一个变体:

  4. 这是一篇关于Linux和CPU缓存的文章:

注意:

在这个(非常非常低)的水平上,"Linux"!="Unix"


pho*_*ger 5

如果您正在编写一个用户模式(而不是内核模式)程序,并且它是单线程的,那么您实际上没有理由首先费心刷新缓存。您的用户模式程序可能会忘记它的存在;它只是为了加快程序的执行速度,操作系统通过处理器的 MMU 对其进行管理。

我认为您可能实际上想要从用户模式应用程序中刷新缓存的原因只有几个:

  1. 您的应用程序旨在在对称多处理器系统上运行,或者与外部硬件进行数据交易)
  2. 您只是测试缓存以进行某种性能测试(在这种情况下,您可能真的应该编写测试以在内核模式下运行,也许作为驱动程序)。

无论如何,假设您使用的是 Linux...

#include <asm/cachectl.h>

int cacheflush(char *addr, int nbytes, int cache);
Run Code Online (Sandbox Code Playgroud)

这假设您有一个刚刚写入的内存块,并且您希望确保它从缓存中刷新回主内存。该块从 addr 开始,长度为 nbytes,位于两个缓存之一(或两者)中:

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

通常,您只需要刷新 DCACHE,因为当您将数据写入“内存”(即缓存)时,它通常是数据,而不是指令。

如果你出于某种奇怪的测试原因想要刷新“所有缓存”,你可以 malloc() 一个你知道比 CPU 缓存大的大块(射击,让它大 8 倍!),写入任何旧的垃圾进入其中,然后冲洗整个块。

另请参阅: 如何在 C++ 中执行缓存操作?


小智 5

这就是英特尔建议刷新缓存的方式:

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");
}
Run Code Online (Sandbox Code Playgroud)

  • 你的来源是什么? (2认同)