此实现中是否承诺缓存失效

Is cache invalidation promised in this implementation

考虑以下代码:

volatile uint32_t word;
for (i=0; i<10; i++)
{
    word = *(uint32_t *)(ADDRESS_IN_MEMORY);
    printf("%"PRIu32, word);
    some_function_compiled_in_other_object();  /* this function may or may not change memory content at adress ADDRESS_IN_MEMORY */
}

所以,由于 word 是易变的,我们知道 word = *(uint32_t *)(ADDRESS_IN_MEMORY) 确实会执行 10 次。但是,这里有关于系统缓存的承诺吗?我希望编译后的代码每次从该地址读取时都会使 ADDRESS_IN_MEMORY before\after 无效,因此 word 将从系统内存而不是缓存中加载值。这是答应了吗?

答案是否取决于编译器是否知道 some_function_compiled_in_other_object 在内存地址 ADDRESS_IN_MEMORY 处更改值?

So, since word is volatile, we know that word = *(uint32_t *)(ADDRESS_IN_MEMORY) will be indeed executed 10 times.

没有

假设CPU有一些寄存器(并且只允许传送值to/from寄存器,不允许数据直接从内存中的一个地方传送到内存中的另一个地方) ,编译后的代码实际上做了更多类似这样的事情:

    for (i=0; i<10; i++)
    {
        CPU_register_1 = *(uint32_t *)(ADDRESS_IN_MEMORY);
        word = CPU_register_1

现在我们还假设编译器优化了代码。它知道 *(uint32_t *)(ADDRESS_IN_MEMORY); 不是易变的,所以它可能会将其转换成这样的东西;

    CPU_register_1 = *(uint32_t *)(ADDRESS_IN_MEMORY);
    for (i=0; i<10; i++)
    {
        word = CPU_register_1

C 标准对高速缓存一无所知。它们是 C 语言范围之外的特定于应用程序的细节。

volatile 关键字只与编译器执行的优化有关。编译器需要确保对 volatile 限定变量的操作按特定顺序排序,而不是优化掉。

读取硬件寄存器时,必须始终使用volatile,否则编译器会假定寄存器的内容自上次使用以来从未更改过。

因此,如果您的示例中的 ADDRESS_IN_MEMORY 是一个与地址相对应的数字,那么您就有一个错误,因为您将其读作 *(uint32_t *)(ADDRESS_IN_MEMORY);。这个错误与缓存内存没有丝毫关系。

缓存内存处理由 CPU/branch 预测处理,而不是由编译器或 C 语言处理。因此,您不能直接从应用程序代码影响它,除非您访问可以指定行为的 MMU 寄存器。它当然是非常系统特定的。健全的系统设置不会将内存映射硬件寄存器访问加载到数据缓存中。

然而,您可以通过连续访问内存来编写缓存友好的代码,始终从上到下读取下一个相邻地址,没有任何可以更改访问顺序的分支。