反序列化/序列化时的gcc/clang优化

反序列化/序列化时的gcc/clang优化,gcc,serialization,clang,compiler-optimization,llvm-clang,Gcc,Serialization,Clang,Compiler Optimization,Llvm Clang,某些gcc/clang编译器优化允许对程序集中代码的执行进行重新排序(例如,对于gcc:-freorder块-freorder块和分区-freorder函数)。在按特定顺序取消/序列化数据结构时,使用此类优化安全吗 例如: void write(int* data,std::ofstream& outstream) { outstream.write(reinterpret_cast<char*>(data),sizeof(int)); } void read(int*

某些gcc/clang编译器优化允许对程序集中代码的执行进行重新排序(例如,对于gcc:-freorder块-freorder块和分区-freorder函数)。在按特定顺序取消/序列化数据结构时,使用此类优化安全吗

例如:

void write(int* data,std::ofstream& outstream)
{
  outstream.write(reinterpret_cast<char*>(data),sizeof(int));
}

void read(int* data,std::ifstream& instream)
{
  instream.read(reinterpret_cast<char*>(data),sizeof(int));
}

void serialize()
{
  std::ofstream ofs("/somePath/to/some.file");
  int i = 1;
  int j = 2;
  int k = 3;

  write(i, ofs);
  write(j, ofs);
  write(k, ofs);

  ofs.close();
}

void deserialize()
{
  std::ifstream ifs("/somePath/to/some.file");
  int i;
  int j;
  int k;

  read(i, ifs);
  read(j, ifs);
  read(k, ifs);

  ifs.close();
}
void写入(int*数据,std::of流和超出流)
{
outstream.write(reinterpret_cast(数据),sizeof(int));
}
无效读取(int*数据,标准::ifstream和instream)
{
流内读取(重新解释流(数据),sizeof(int));
}
void serialize()
{
std::ofs流(“/somePath/to/some.file”);
int i=1;
int j=2;
int k=3;
写入(i,ofs);
写入(j,ofs);
写入(k,ofs);
ofs.close();
}
void反序列化()
{
std::ifstream ifs(“/somePath/to/some.file”);
int i;
int j;
int k;
阅读(i,ifs);
阅读(j,ifs);
阅读(k,ifs);
ifs.close();
}

-freorder块
-freorder块和分区
,以及
-freorder函数
都会影响代码在可执行文件中的排列顺序:


  • -freorder blocks
    允许gcc重新排列组合在一起形成函数的汇编代码的直线块,以尽量减少CPU可能造成的分支预测未命中次数

  • -freorder函数
    获取编译器认为不太可能执行的函数,并将它们移动到可执行文件的较远部分。这样做的目的是尝试将尽可能多的频繁执行的代码打包到尽可能少的内存中,以便尽可能多地受益于指令缓存

  • -freorder块和分区
    类似于
    -freorder函数
    ,但在程序集块级别。如果您的代码中有
    If(不太可能(foo)){x=1;}
    分支,那么编译器可能会选择使用表示
    x=1
    并将其移开频繁执行的代码

这些都不会影响程序的控制流。所有优化都将保证,如果您先将
i
写入一个文件,然后再将
j
写入一个文件,那么在应用优化后仍然会观察到这一点