在 c++ 中,内存写入可以通过优化延迟还是我需要易失性
In c++ can memory writes be delayed by optimization or do I need volatile?
我已经在这里阅读了数十个关于使用易失性的问题和答案,我很抱歉发布了另一个问题和答案,但我认为我没有确切地看到我正在寻找的内容。
我有一个用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。
- 易失性sig_atomic_t的内存安全性
- C++易失性:保证 32 位访问?
- 避免易失性和非易失性成员函数的代码重复
- 当 2 个线程共享同一物理内核时,具有错误共享的易失性增量在发布中的运行速度比在调试中慢
- 如何访问常量易失性 std::array?
- 为什么在 C++20 中弃用易失性?
- 根据 MSVC,具有易失性成员的结构不再是 POD
- 是否允许编译器优化掉局部易失性变量
- 访问共享内存而不使用易失性、std::atomic、信号量、互斥锁和自旋锁
- 如何避免对无锁程序使用易失性?
- C++:易失性实例中的易失性成员函数 - 将数组分配给指针是无效的转换?
- g++ 6.3,avx 内联函数上的 Kahan 求和用易失性关键字进行序列化
- 是什么让这种易失性打破了结构的指针算法?
- 如果不需要易失性,为什么 std::atomic 方法会提供易失性重载
- *(易失性无符号整数 *) 的含义 0x00 = 0x00;
- 使用易失性 c 字符串和 std::cout
- 易失性结构 = 结构不可能,为什么?
- 如何强制 GCC 以线性方式转换易失性内联程序集语句
- 我可以使用互斥锁或关键字(静态)代替C++中的易失性吗?
- 在 c++ 中,内存写入可以通过优化延迟还是我需要易失性