我正在查找关键字volatile以及它的用途,我得到的答案非常多:
它用于防止编译器优化代码.
有一些示例,例如轮询内存映射硬件时:没有volatile轮询循环将被删除,因为编译器可能会识别出条件值永远不会更改.但由于只有一个例子或两个例子,它让我思考:volatile在避免不必要的优化方面我们还需要使用其他情况吗?条件变量是唯一volatile需要的地方吗?
我认为优化是特定于编译器的,因此未在C++规范中指定.这是否意味着我们必须通过直觉,说嗯,我怀疑如果我没有声明该变量volatile或者是否有任何明确的规则,我的编译器将废除它?
volatile uint8_t reset_mask[768] = {0}
Run Code Online (Sandbox Code Playgroud)
现在我在一个内部操作期间将此数组元素的值设置为1.
在另一个函数调用中,我需要将此数组的所有元素设置为0.一种方法是使用for循环,但我相信更好的方法来分配数组的所有元素是使用memset
memset(reset_mask, 0, sizeof(reset_mask));
Run Code Online (Sandbox Code Playgroud)
但是我收到了这个错误: - "从类型'易失性uint8_t*{aka volatile unsigned char*}'转换为'void*'类型转换为限定符"
如果我们不能在这里使用memset,有没有更好的方法一次性设置这个volatile数组的所有元素?
有了这两个问题作为背景(第一和第二),我很好奇C++编译器在处理指针时可以执行多少优化?更具体地说,我对编译器在优化它可能检测到的永远不会运行的代码时的智能感兴趣.
(有些人可能会指出,这可能是这个问题的一个骗局,但它的这一特定部分并未得到完全回答.因此我决定开始一个只涉及这个问题的新问题.)
(我不是C++专家,所以我在下面的陈述中可能会出错,但无论如何我都会试一试).C++编译器可以优化掉它将识别的部分代码,它们永远不会被执行或永远不会被退出(例如循环).这是一个例子:
void test() {
bool escape = false;
while ( !escape ); // Will never be exited
// Do something useful after having escaped
}
Run Code Online (Sandbox Code Playgroud)
编译器很可能会认识到循环永远不会被退出,因为代码永远不会改变值,escape以便退出循环.这使得循环无用.
现在,如果我们要将变量更改为指针,编译器是否仍然会优化循环?说代码看起来像这样:
void test( bool* escape ) {
while ( *escape ); // Will this be executed?
// Do something useful after having escaped
}
Run Code Online (Sandbox Code Playgroud)
我怀疑编译器会取消循环,否则关键字volatile将是多余的,是吗?但是当处理线程时 - 实际上它已被修改但在函数之外,甚至可能在C++文件之外 - 编译器是否仍会删除循环?如果指向的变量escape是全局变量,或者是另一个函数中的局部变量,它会有所不同吗?编译器可以进行此检测吗?在这个问题中,有人说如果在循环内部调用库函数,编译器将不会优化循环.当使用阻止此优化的库函数时,会有什么机制?
我对volatile使用情况有疑问.我通常会尝试跨线程共享的所有变量都有volatile关键字以确保直接内存访问,当然还有互斥锁保护.
但是,volatile如果共享变量以确保一致性,是否真的需要?
我用一个例子来解释:
Thread1: //(affects it behaviour with the variable)
mymutex.lock();
if(variable)
{
...
variable = false;
}
mymutex.unlock();
Run Code Online (Sandbox Code Playgroud)
Thread2:
mymutex.lock();
variable = true;
mymutex.unlock();
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,thread2仅写入和thread1读/写.是否可能variable缓存并且线程不读取新值?即使互斥锁设置正确吗?volatile在这种情况下我需要吗?
我问这个因为而不是变量我有一个std::vector,它不能挥发.如果没有volatile关键字,我不能100%确定这种方法是安全的.
谢谢.
编辑:正确地重新制定问题.