volatile 关键字和 RAII 习语 (C++)
volatile keyword and RAII idiom (C++)
假设有一个 class 来控制对与此类似的(关键)代码块的并发访问:
class RAIIObj : public boost::noncopyable {
public:
explicit RAIIObj( LockObj& Obj ) : LkObj( Obj ) { Obj.Acquire(); }
~RAIIObj() { try { Obj.Release(); } catch (...) {} }
private:
LockObj& LkObj;
};
使用这样一段代码时,是否需要使用volatile关键字
不是看到代码被优化了吗?
比如我要写
ALockingObj LockObj;
void AFunc() {
RAIIObj LKGuard( LockObj );
// do some MT stuff
}
或
ALockingObj LockObj;
void AFunc() {
volatile RAIIObj LKGuard( LockObj );
// do some MT stuff
}
为了确保LKGuard一直存在?
因为 LKGuard 是一个局部变量,在主体的任何地方都没有使用
函数,如果我不使用 volatile 关键字可以优化掉吗?
谢谢
不,您不需要将其声明为易变的。编译器可以看到实例化 lkobj 做了一大堆无法优化的东西(与 int lkobj;
相比,后者显然什么都不做)
虽然 pm100 提供的答案就标准而言确实是正确的,但我发现 GCC 4.9 可以优化 RAII 类型(优化标志:-Os -flto
)。这是优化器丢弃的代码:
class MutexLocker
{
chibios_rt::Mutex& mutex_;
public:
MutexLocker(chibios_rt::Mutex& m) : mutex_(m)
{
mutex_.lock();
}
~MutexLocker()
{
mutex_.unlock();
}
};
使类型易变解决了问题:
namespace impl_
{
class MutexLockerImpl
{
chibios_rt::Mutex& mutex_;
public:
MutexLockerImpl(chibios_rt::Mutex& m) : mutex_(m)
{
mutex_.lock();
}
~MutexLockerImpl()
{
mutex_.unlock();
}
};
}
using MutexLocker = volatile impl_::MutexLockerImpl;
因此,尽管标准没有要求,但我建议显式声明 RAII 类型为 volatile 以进行积极优化。
假设有一个 class 来控制对与此类似的(关键)代码块的并发访问:
class RAIIObj : public boost::noncopyable {
public:
explicit RAIIObj( LockObj& Obj ) : LkObj( Obj ) { Obj.Acquire(); }
~RAIIObj() { try { Obj.Release(); } catch (...) {} }
private:
LockObj& LkObj;
};
使用这样一段代码时,是否需要使用volatile关键字 不是看到代码被优化了吗?
比如我要写
ALockingObj LockObj;
void AFunc() {
RAIIObj LKGuard( LockObj );
// do some MT stuff
}
或
ALockingObj LockObj;
void AFunc() {
volatile RAIIObj LKGuard( LockObj );
// do some MT stuff
}
为了确保LKGuard一直存在?
因为 LKGuard 是一个局部变量,在主体的任何地方都没有使用 函数,如果我不使用 volatile 关键字可以优化掉吗?
谢谢
不,您不需要将其声明为易变的。编译器可以看到实例化 lkobj 做了一大堆无法优化的东西(与 int lkobj;
相比,后者显然什么都不做)
虽然 pm100 提供的答案就标准而言确实是正确的,但我发现 GCC 4.9 可以优化 RAII 类型(优化标志:-Os -flto
)。这是优化器丢弃的代码:
class MutexLocker
{
chibios_rt::Mutex& mutex_;
public:
MutexLocker(chibios_rt::Mutex& m) : mutex_(m)
{
mutex_.lock();
}
~MutexLocker()
{
mutex_.unlock();
}
};
使类型易变解决了问题:
namespace impl_
{
class MutexLockerImpl
{
chibios_rt::Mutex& mutex_;
public:
MutexLockerImpl(chibios_rt::Mutex& m) : mutex_(m)
{
mutex_.lock();
}
~MutexLockerImpl()
{
mutex_.unlock();
}
};
}
using MutexLocker = volatile impl_::MutexLockerImpl;
因此,尽管标准没有要求,但我建议显式声明 RAII 类型为 volatile 以进行积极优化。