C++;对象数据成员的连续内存访问 我很好奇内存模型是如何为C++类工作的。具体地说,我是否保证对象的数据成员是连续分配的。例如,如果我有以下代码: 类粒子{ 公众: 粒子(双ix、双iy、双ivx、双ivy); //为简洁起见省略 私人: 双x; 双y; 双vx; 双vy; };
当我初始化一个对象时,数据成员在内存中是连续的还是(为了性能)我最好这样做:C++;对象数据成员的连续内存访问 我很好奇内存模型是如何为C++类工作的。具体地说,我是否保证对象的数据成员是连续分配的。例如,如果我有以下代码: 类粒子{ 公众: 粒子(双ix、双iy、双ivx、双ivy); //为简洁起见省略 私人: 双x; 双y; 双vx; 双vy; };,c++,performance,oop,memory,c++17,C++,Performance,Oop,Memory,C++17,当我初始化一个对象时,数据成员在内存中是连续的还是(为了性能)我最好这样做: 类粒子{ 公众: 粒子(双ix、双iy、双ivx、双ivy); //为简洁起见省略 私人: std::数组参数 }; 我有Fortran和C编程的背景,我习惯于使用数组进行快速顺序内存访问,因此我想知道,当所有数据成员在任何调用中连续使用时,上述语义之一是否更适合用于快速访问。 标准保证了它们在内存中的顺序 (如果你记下他们的地址,他们会增加) 它不保证它们在连续内存中;但如果这是最理想的布局,那么它们可能会是。
类粒子{
公众:
粒子(双ix、双iy、双ivx、双ivy);
//为简洁起见省略
私人:
std::数组参数
};
我有Fortran和C编程的背景,我习惯于使用数组进行快速顺序内存访问,因此我想知道,当所有数据成员在任何调用中连续使用时,上述语义之一是否更适合用于快速访问。
- 标准保证了它们在内存中的顺序
(如果你记下他们的地址,他们会增加) - 它不保证它们在连续内存中;但如果这是最理想的布局,那么它们可能会是。允许编译器在成员之间添加填充(它通常这样做是为了提高访问效率(牺牲空间换取速度))。如果所有成员大小相同,则不太可能出现这种情况
std::array
可能有用的用例(成员通过索引访问)
注释std::vector
中建议也可以使用。这是正确的,标准保证成员位于相邻位置,但它们可能不是对象的本地成员(在std::array
中,它们是对象的本地成员)。- 标准保证了它们在内存中的顺序
(如果你记下他们的地址,他们会增加) - 它不保证它们在连续内存中;但如果这是最理想的布局,那么它们可能会是。允许编译器在成员之间添加填充(它通常这样做是为了提高访问效率(牺牲空间换取速度))。如果所有成员大小相同,则不太可能出现这种情况
std::array
可能有用的用例(成员通过索引访问)
注释
std::vector
中建议也可以使用。这是正确的,标准保证成员位于相邻位置,但它们可能不是对象的本地成员(在std::array
中,它们是对象的本地成员)。是的,可以保证顺序与声明中的顺序相同
分配具有相同访问控制的(非联合)类的非静态数据成员,以便以后的成员在类对象中具有更高的地址。未指定具有不同访问控制的非静态数据成员的分配顺序。实施一致性要求可能会导致两个相邻的成员不能紧随其后进行分配;管理虚拟函数和虚拟基类的空间需求也是如此
是的,我们保证订单和申报单上的一样 分配具有相同访问控制的(非联合)类的非静态数据成员,以便以后的成员在类对象中具有更高的地址。未指定具有不同访问控制的非静态数据成员的分配顺序。实施一致性要求可能会导致两个相邻的成员不能紧随其后进行分配;管理虚拟函数和虚拟基类的空间需求也是如此 [元答案] 我(表现)好吗 为什么连续分配数据成员必然会提高性能?事实上,因为像double这样的东西需要适当地对齐,所以通常情况正好相反(这就是为什么编译器不总是这样做的原因)。[Meta-answer] 我(表现)好吗
为什么连续分配数据成员必然会提高性能?事实上,因为像
std::array
和std::vector
是唯一保证连续分配的std容器。与数据成员相比,它可能会增加很小的性能损失。@Rip2 std::vector也保证了这一点。
class Particle {
public:
Particle(double ix, double iy, double ivx, double ivy);
// Omitted for brevity
private:
std::array<double, 4> params
};