我的理解是,C++ 允许对 IO 或外部函数调用以外的任何内容进行优化重新排序。这开始让我编写 RAII 风格函数时间戳的努力受挫。
编辑
这是一个独立的示例,
VS 2012 代码,经过优化
#include <chrono>
#include <iostream>
#include <atomic>
#include <string>
using namespace std;
class TimeSlice
{
public:
TimeSlice(std::string myname): name(myname), start(timestamp())
{
fency();//don't optomize me out!
}
~TimeSlice()
{
fency();
auto elapsed = timestamp()-start;
cout << name<<(int) elapsed << endl;
}
static inline long long timestamp()
{
return chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
}
private:
const long long start;
const std::string name;
static inline void fency()
{
std::atomic_signal_fence(std::memory_order_seq_cst);
}
};
最佳答案
函数调用没有被优化,而是被重新排序。它的编译方式如下:
_sleep(10);
start = timestamp();
elapsed = timestamp()-start;
cout << name<<(int) elapsed << endl;
这种重新排序是合法的,因为 _sleep 和时间戳都不构成 IO。如果您有 c++11 支持,您可以使用信号处理程序内存栅栏来防止此类重新排序。只需包含并插入:
std::atomic_signal_fence(std::memory_order_seq_cst);
位于析构函数和构造函数主体的开头。对于 x86_&4 上的 GCC 4.7 和 4.8,这样的内存栅栏不会生成任何代码,只会限制编译器重新排序。
关于c++ - 如何防止时间戳被重新排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22278963/