美文网首页
C++ 中 volatile关键字有什么用?

C++ 中 volatile关键字有什么用?

作者: wayyyy | 来源:发表于2021-02-28 03:31 被阅读0次
    int func(int& a)
    {
        int b = a;
        int c = a;
        return a + b + c;
    }
    
    int main()
    {
        int a = 1;
        return func(a);
    }
    

    利用 g++ test.cpp -g -O2 -o test.out && objdump -S test.out

    Disassembly of section .text:                               
                                                                
    00000000000004f0 <main>:                                    
                                                                
    int main()                                                  
    {                                                           
        int a = 1;                                              
        return func(a);                                         
    }                                                           
     4f0:   b8 03 00 00 00          mov    $0x3,%eax            
     4f5:   c3                      retq                        
     4f6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1) 
     4fd:   00 00 00                                            
    

    从上面看出,func(a) 这个函数调用,直接被优化掉了。

    这么优化有什么问题吗?
    单线程没问题,但多线程就有问题了,如果是多线程,a的值虽然在当前上下文中不会被修改,但可能正在被其他线程修改啊。于是上面的优化就不对了。(假设我们需要做的是无锁编程,有锁编程自然不会需要用到volatile关键字)

    那么,volatile关键字在这里就可以帮助我们了,volatile关键字提醒编译器: a可能随时被意外修改,意外的意思是虽然当前这段代码里看起来a不会变,但可能别的地方正在修改a的值,所谓"别的地方",某些情况下指的就是其他线程了。

    下面是加上volatile关键字后的汇编代码。

    int fun(volatile int& a)
    {
        int b = a;
        int c = a;
        return a+b+c;
    }
    
    int main()
    {
        volatile int a = 1;
        return fun(a);
    }
    

    利用 g++ test2.cpp -g -O2 -o test2.out && objdump -S test2.out

    Disassembly of section .text:                                   
                                                                    
    00000000000004f0 <main>:                                        
        return a + b + c;                                           
    }                                                               
                                                                    
    int main()                                                      
    {                                                               
        volatile int a = 1;                                         
     4f0:   c7 44 24 fc 01 00 00    movl   $0x1,-0x4(%rsp)          
     4f7:   00                                                      
        int b = a;                                                  
     4f8:   8b 44 24 fc             mov    -0x4(%rsp),%eax          
        int c = a;                                                  
     4fc:   8b 54 24 fc             mov    -0x4(%rsp),%edx          
        return a + b + c;                                           
     500:   8b 4c 24 fc             mov    -0x4(%rsp),%ecx          
     504:   01 c8                   add    %ecx,%eax                
     506:   01 d0                   add    %edx,%eax                
        return func(a);                                             
    }                                                               
     508:   c3                      retq                            
     509:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)                
    

    另外注意:volatile 其实是写给编译器看的东西,CPU无感知,也就是说它没有定义 happens-before 的关系,不能当作传统的原子变量来用。

    相关文章

      网友评论

          本文标题:C++ 中 volatile关键字有什么用?

          本文链接:https://www.haomeiwen.com/subject/dinadktx.html