在 c++ 中,内存写入可以通过优化延迟还是我需要易失性

In c++ can memory writes be delayed by optimization or do I need volatile?

本文关键字:延迟 易失性 优化 可以通过 c++ 内存      更新时间:2023-10-16

我已经在这里阅读了数十个关于使用易失性的问题和答案,我很抱歉发布了另一个问题和答案,但我认为我没有确切地看到我正在寻找的内容。

我有一个用C++为Arduino微控制器编写的库。我有一个填充缓冲区的 ISR,完成后它会设置一个标志,让外界知道有可用的数据。我有缓冲区,一个变量告诉缓冲区中有多少字节,还有一个标志告诉世界缓冲区有数据。一旦我在 ISR 中设置了"我完成了填充缓冲区"标志,ISR 将永远不会再次更改缓冲区或其长度,直到/除非我重新启用内容。

通常,我已经将标志、缓冲区和长度值都声明为易失性,因为这是您应该在 ISR 例程中执行的操作。

但是,一旦缓冲区已满,我就会对其进行大量处理,这意味着我正在欺骗自己进行一些潜在的优化。在我的 ISR 之外,如果我有读取类似内容的代码

if (flag== FINISHED) {
  disable_my_ISR (); 
   /*do a bunch of stuff with the buffer*/
  reenable_my_ISR();
}

那么从理论上讲,我认为我不需要让我的缓冲区如此不稳定。这是对的吗?正如我所说,我担心的是我的"用缓冲区做一堆事情"没有得到优化,因为缓冲区是易失性的。

我在这个论坛上看到的唯一另一个答案是这个,但我不确定这是否真的是相同的情况。

当你将某物标记为volatile时,你是在说它的值可能会在代码中的写入/读取之间发生变化。这正是 ISR 访问变量时可能发生的情况,因此您需要volatile .

ISR 和主代码之间共享的任何变量都应volatile 。您的代码可能会在不标记所有内容的情况下工作,但它最终会回来咬您。

那么从理论上讲,我认为我不需要让我的缓冲区如此不稳定。

不可以,如果您的主代码和 ISR 同时使用缓冲区,则需要将其标记为volatile。我认为您可能过于担心缺少优化。您始终可以将volatile数组复制到普通数组中,进行处理并计时差异。

甚至不是说内存写入可以通过优化来延迟 - 如果您的缓冲区未声明为volatile,您的编译器可能会删除使用它的任何代码。举个例子:

int myBuffer[5] = {0};
if(flag == FINISHED) {
    printf("%d", myBuffer[0]);
}

这很可能总是打印0,即使您的 ISR 更改了缓冲区的值,因为编译器不知道 ISR 如何更改程序流,因此假设myBuffer[0]在使用时将为 0。