c++ - 成员变量(属性)可以驻留在 C++ 中的寄存器中吗?

标签 c++ attributes member volatile cpu-registers

局部变量(比如 int)可以存储在处理器寄存器中,至少只要它的地址在任何地方都不需要。考虑一个计算某些东西的函数,比如一个复杂的散列:

int foo(int const* buffer, int size)
{
    int a;   // local variable
    // perform heavy computations involving frequent reads and writes to a
    return a;
}

现在假设缓冲区不适合内存。我们编写了一个类来计算数据 block 的哈希值,多次调用 foo:

struct A
{
    void foo(int const* buffer, int size)
    {
        // perform heavy computations involving frequent reads and writes to a
    }

    int a;
};

A object;
while (...more data...)
{
    A.foo(buffer, size);
}
// do something with object.a

这个例子可能有点做作。这里的重要区别是 a 是自由函数中的局部变量,现在是对象的成员变量,因此状态在多次调用中得以保留。

现在的问题是:编译器将 foo 方法开头的 a 加载到寄存器中并在末尾将其存储回来是否合法?实际上,这意味着监视对象的第二个线程永远无法观察到 a 的中间值(除了同步和未定义的行为)。如果速度是 C++ 的主要设计目标,这似乎是合理的行为。标准中是否有任何内容可以阻止编译器执行此操作?如果不是,编译器真的会这样做吗?换句话说,除了在函数开始和结束时加载和存储一次成员变量之外,我们是否可以预期使用成员变量会带来(可能很小的)性能损失?

据我所知,C++ 语言本身甚至没有指定寄存器是什么。但是,我认为这个问题无论如何都很清楚。无论这是否重要,我都感谢标准 x86 或 x64 架构的答案。

最佳答案

如果(且仅当)编译器可以证明在 foo 执行期间没有其他任何东西可以访问 a,则编译器可以这样做。
一般来说,这是一个非常重要的问题;我认为没有任何编译器试图解决它。

考虑(更人为的)例子

struct B
{
    B (int& y) : x(y) {}
    void bar() { x = 23; }
    int& x;
};

struct A
{
    int a;
    void foo(B& b)
    {
        a = 12;
        b.bar();            
    }
};

看起来很天真,但后来我们说

A baz;
B b(baz.a);
baz.foo(b);

“优化”这会在 baz.a 中留下 12,而不是 23,这显然是错误的。

关于c++ - 成员变量(属性)可以驻留在 C++ 中的寄存器中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39978960/

相关文章:

jquery - 选择值列表中具有属性值的元素

class - 我无法从 Kotlin 的嵌套类中联系到任何类成员

c++ - 为类成员返回 const std::string& 与 const char*

java - MANIFEST.MF 属性返回 null

c++ - SDL 将光标更改为 Windows 默认值

c++ - 如何在各种显示器上使用 Qt/C++ 获取打印屏幕?

c++ - 最佳情况下,如果一个变量在多个线程中读取但仅在一个线程中写入,那么是否应该在写入线程中非原子地读取该变量?

datetime - AttributeError:模块 'datetime' 没有属性 'now'

c++ - 完美转发到数据成员的成员函数?

C++ const 数组追加