【问题标题】:Performance difference between POD and non-POD classesPOD 和非 POD 类之间的性能差异
【发布时间】:2019-02-11 10:13:12
【问题描述】:

我很难理解为什么我的编译器(g++ 8.1.0 和 clang++ 6.0.0)对待 POD(plain-old-data)和非 POD 代码的方式不同。

测试代码:

#include <iostream>

struct slong {
  int i;
  ~slong() { i = 0; }
};

int get1(slong x) { return 1+x.i; }

int main() {
  std::cerr << "is_pod(slong) = " << std::is_pod<slong>::value << std::endl;
}

使用析构函数(因此不是 POD)定义一个类 slong,并且带有 -Ofast 的编译器将为 get1 生成

        movl    (%rdi), %eax
        incl    %eax

但是当我注释掉析构函数时(所以slong 变成了 POD)我得到了

        leal    1(%rdi), %eax

当然,性能问题是次要的;我还是想明白。在其他(更复杂的)情况下,我还注意到更显着的代码差异。

【问题讨论】:

  • 请注意,析构函数中的操作是没有意义的int 即将不复存在,谁在乎它的价值是什么?

标签: c++ compiler-optimization register-allocation


【解决方案1】:

注意movl 访问内存,而leal 不访问。

struct 按值传递给函数时,如果它是 POD,ABI 可以将其填充到寄存器 (rdi) 中。

如果struct 不是 POD,ABI 必须在堆栈上传递它(大概是因为代码可能需要它的地址来调用析构函数、访问 vtable 和执行其他复杂的操作)。所以访问它的成员需要间接的。

【讨论】:

  • 啊,好吧,如果要包装整数之类的东西,似乎不应避免使用非 POD 结构。
  • 我想说非 POD 结构应该避免正是因为这个原因! Zero overhead principle.
猜你喜欢
  • 2011-08-13
  • 1970-01-01
  • 2021-02-03
  • 2011-01-19
  • 2018-12-29
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
相关资源
最近更新 更多