给优化器更大的“许可证”

时间:2016-04-15 21:28:53

标签: c++ c gcc optimization

我知道volatile变量背后的概念。基本上所有对该变量的读写都必须。有没有办法允许优化器只使用所有的写操作,并假设读取将始终保持不变(除非通过写入修改)。

另外(沿着相同的行)有一种方法可以为编译器定义一种新类型的内存来存储变量。例如,如果我有一个带有SD卡的微控制器,我可以将SD卡定义为存储内存的地方(或者我必须自己完成所有的读/写操作)。

对于记录,我使用gcc作为我的编译器,如果有什么我可以在gcc上专门做(并且只有)

4 个答案:

答案 0 :(得分:4)

  

我知道volatile变量背后的概念。

确定...

  

基本上必须对该变量进行所有读写操作。

绝对不是“基本上”。

  

是否有办法允许优化器只使用所有写操作并假设读取始终保持不变(除非通过写入修改)。

没有

< - snip - >

volatile用于建模对内存映射I / O的读/写访问。 “写入”此类I / O通常会触发电子设备中的活动,即使写入的值与先前写入的值相同。

没有其他用于volatile的东西 - 不,甚至在多线程中都没有(无论如何它都不会做你想要的)。

来自§7.1.6.1

  

[注意:volatile是实现的提示,以避免涉及对象的激进优化   因为对象的值可能会被实现无法检测的方式更改。此外,   对于某些实现,volatile可能表示需要访问特殊硬件指令   物体。有关详细语义,请参见1.9。通常,volatile的语义是有意的   在C ++中与在C中相同。 - 尾注]

这里的含义是,除非你完全理解实现对volatile变量的作用,否则你没有地方使用它。

它的使用是不可移植的,所以如果使用它,应该包含在你正在处理的任何概念的特定于实现的专门化中。

答案 1 :(得分:1)

如何简单地抛弃读取的波动性?

原来并不简单。

以下似乎只能在clang上可靠地运行。并且只有在执行volatile写操作之前创建hw_reg_read别名。

volatile int * hw_reg = (int*)0x0001003B;

int main()
{
    /*obtain nonvolatile alias*/
    int* hw_reg_read = const_cast<int*>(hw_reg);

    /*volatile write*/
    *hw_reg = 42;

    /*nonvolatile read*/
    int i = *hw_reg_read;

    return i;
}

我现在将其作为稻草人留在这里。

答案 2 :(得分:0)

在较高级别,您可以使用智能指针,discussed here

你正在谈论给某个变量另一个属性(至少)。如果变量具有给定属性,则在访问它时采取不同的操作(读或写)。

为此,您需要修改编译器。这是可能的。例如,8051编译器具有允许位访问和变量页访问的属性。许多嵌入式系统的编译器都具有将变量放在特定内存块中的语法。

我建议先尝试使用智能指针包装器。

另一个想法是将变量放入一个类中,并提供 getters setters 来为您的环境建模(不允许直接访问)。

答案 3 :(得分:0)

我认为这可能就是我想要的:

template<class T>
class smartWriter{
    volatile T* Volatile;  //Use this for writes
    T* NotVol;  //Use this for reads
    public:
        smartWriter(T* add) : Volatile(add),NotVol(add){
        }
        operator T&() const{
            return *NotVol;  //reads involve the non volatile one
        }
        void operator=(T data){
            *Volatile = data;  //writes involve the volatile one
        }

};

int main(int argc,char** args){
    smartWriter<int> smtVar(((int*)0xdeadbeaf)) ;  //Initialize var with address "0xdeadbeef"
    smtVar = 12;  //Optimizer can not get rid of this
    int other = smtVar;  //Optimizer might get rid of this?

    system("Pause");
}

感谢用智能指针激发我的想象力......