【问题标题】:c++ - struct and class paddingc++ - 结构和类填充
【发布时间】:2015-09-04 10:21:45
【问题描述】:

我总是在 C 中填充我的结构以获得最佳性能(良好的内存对齐)。

// on a x86_64 
struct A {

 int64_t z;
 int32_t x;
 int16_t y;
 // we don't care the uint8_t position, as they are 1 byte wide.
 uint8_t s[8];
 uint8_t t[4];

}

但如果我决定走 c++ 路线,为其他目的创建一个对象,我需要一个类:

class B {

   B(){}
  ~B(){}

 public:
   int64_t a;
   int8_t  b;

 private:
   int32_t c;

//methods...
}

那么,c 就不再对齐了。

有没有办法避免这样做(多个标签):

class B {

  B(){}
  ~B(){}

 public:
   int64_t a;

 private:
   int32_t c;

 public:
   int8_t  b;

}

(在某些 CPU 上,对齐很重要)。 谢谢

【问题讨论】:

  • 我怀疑这个类没有对齐
  • 这不是关于类,而是关于它里面的变量。我找不到任何说它是自动对齐和正确组织的。我不想丢失太多字节。
  • 我怀疑班级成员没有对齐
  • 在您用尽所有其他优化之前,您甚至不应该考虑对您的代码执行此操作吗?首先编写可读性好的代码,然后找出需要修剪的地方。

标签: c++ class struct alignment


【解决方案1】:

你的努力完全是浪费时间。编译器会正确对齐自己(如果您没有明确告诉他不要这样做)。 它在成员之间插入字节。它会在结构的末尾插入足够的字节,使其整体大小是结构对齐规则的倍数。

你的努力也适得其反。如果用其他对齐规则为另一个架构编译?然后编译器将填充字节插入到您的填充字节中。

仅当数据交换超出编译器或架构范围时,显式对齐和打包结构才有意义。

【讨论】:

  • 错了。你不明白,有时我们需要正确的对齐方式和结构/类的最小大小。
  • 你说得对,编译器会正确地对齐东西以提高性能,这是 OP 所问的,但其他人可能仍想执行该任务以节省因填充而丢失的内存
  • 填充有时很重要——将原子变量放在不同的缓存行以防止错误共享是我想到的主要示例。不幸的是,它确实往往是特定于平台的。
  • @Kroma 如果您想要最小尺寸,那么您必须更改会员的顺序。手动填充无法以任何方式帮助您节省内存。
  • @vlad_tepesch:是的,我知道!谢谢
【解决方案2】:

是的。将所有状态放在一个结构中,根据需要对齐和填充。最好在结构上没有成员函数,让它变得微不足道。该类拥有此结构的私有实例。类成员函数直接作用于这个状态。

应该够了。另外,您可以清楚地将状态和功能分开,这总是很好的。倾向于与类中的 set/get 函数一起使用,除非您特别喜欢使用不一致的语法进行函数调用和状态访问。

Alignas 也可能很有趣。

【讨论】:

  • 这是一个有趣的想法,乔恩
  • 你可以直接在课堂上做同样的事情。以适当的顺序将所有成员设为私有并使用函数访问它们。结果是相同的,您不必一直取消引用附加级别(没有语义)。
猜你喜欢
  • 1970-01-01
  • 2012-11-14
  • 2014-10-12
  • 2015-04-25
  • 1970-01-01
  • 2023-04-03
  • 2017-06-08
  • 2019-07-09
  • 1970-01-01
相关资源
最近更新 更多