我有一个看起来像这样的结构:
struct SoA
{
int arr1[COUNT];
int arr2[COUNT];
};
我希望它看起来像这样:
struct AoS
{
int arr1_data;
int arr2_data;
};
std::vector<AoS> points;
尽快。订单必须保留。
是单独构造每个AoS
对象并将其推回最快的方法,还是有更快的选项?
SoA before;
std::vector<AoS> after;
for (int i = 0; i < COUNT; i++)
points.push_back(AoS(after.arr1[i], after.arr2[i]));
在Stackoverflow上有SOA/AOS相关的问题,但我没有发现与最快的转换有关的问题。由于结构包装差异,我看不到任何方法可以避免将数据从一种格式复制到另一种格式,但是我希望有人可以告诉我有一种方法可以以不同的方式引用数据并避免副本。
特别鼓励墙壁解决方案。
SoA
和 AoS[]
/ std::vector<AoS>
的二进制布局是不同的,因此,没有复制操作,实际上无法将一个布局转换为另一个。
您拥有的代码非常接近最佳 - 一个改进也许可以预先分配为具有预期元素数量的向量。另外,尝试使用原始元素和构造全元初始化的原始数组。需要仔细测量更改(绝对使用带有您期望的数组尺寸的完全优化的构建来测量),并加权代码的重读/正确性。
如果您不需要确切的二进制布局(似乎是使用矢量的情况),则可以通过创建几个自定义类别以不同方式来揭示现有数据的自定义类,从而实现类似的外观语法。这将避免完全复制。
您需要"阵列"类型(在SoA
的实例上提供索引/迭代)和"元素"类型(用referece以SOA和索引的实例初始化,在该索引上展示单独字段的访问者)
代码的粗略草图(添加迭代器,...):
class AoS_Element
{
SoA& soa;
int index;
public:
AoS_Element(SoA& soa, int index) ...
int arr1_data() { return soa.arr1[index];}
int arr2_data() { return soa.arr2[index];}
}
class AoS
{
SoA& soa;
public:
AoS(SoA& _soa):soa(_soa){}
AoS_Element operator[](int index) { return AoS_Element(soa, index);}
}