对象数据成员的C ++连续内存访问

时间:2018-07-10 16:59:37

标签: c++ performance oop memory c++17

我很好奇内存模型如何用于C ++类。具体来说,是否可以保证对象的数据成员是连续分配的。例如,如果我有以下代码:

class Particle {
public:
  Particle(double ix, double iy, double ivx, double ivy);
  // Omitted for brevity

private:
  double x;
  double y;
  double vx;
  double vy;
};

当我初始化一个对象时,数据成员将在内存中是连续的,还是我最好(为了提高性能)执行以下操作:

class Particle {
public:
  Particle(double ix, double iy, double ivx, double ivy);
  // Omitted for brevity

private:
  std::array<double, 4> params
};

我来自Fortran和C编程的背景,我习惯于使用数组进行快速顺序内存访问,因此我很好奇当所有数据成员在任何调用上连续使用时,上述语义之一是否适合快速访问

3 个答案:

答案 0 :(得分:4)

  • 标准保证它们在内存中的排列顺序为
    (如果您选择了他们的地址,他们将会增加)。

  • 它不会保证它们将位于连续内存中;但是,如果那是最理想的布局,那么它们可能会是。允许编译器在成员之间添加填充(通常这样做是为了提高访问效率(牺牲速度的空间))。如果所有成员的大小都相同,则不太可能。

注意:在它们之间引入public / private / protected会使事情变得复杂,并且可能会改变顺序。

您最好使用数组吗?

这取决于。您通常会通过索引还是通过名称访问它们?我会说99%的时间是您拥有的第一个版本更好,但是我可以想象用std::array<>有用的用例(通过索引访问成员)。

也可以使用注释std::vector<>中的建议。确实如此,并且该标准保证成员位于相邻位置,但它们可能不在对象本地(在std::array<>中,它们在对象本地)。

答案 1 :(得分:1)

是的,可以保证顺序与[class.mem].19声明中的顺序相同

  分配具有相同访问控制的(非联盟)类的

非静态数据成员,以使稍后的成员在类对象中具有更高的地址。未指定具有不同访问控制的非静态数据成员的分配顺序。实施一致性要求可能会导致两个相邻成员不能彼此立即分配;管理虚拟功能和虚拟基类的空间要求也可能如此。

答案 2 :(得分:0)

[元答案]

我最好(为了表现)...

为什么连续分配数据成员必然会提高性能?实际上,由于double之类的东西需要适当对齐,因此通常情况恰恰相反(这就是编译器并不总是这样做的原因)。