gpt4 book ai didi

c++ - 数组结构和结构数组 - 性能差异

转载 作者:IT老高 更新时间:2023-10-28 23:00:26 35 4
gpt4 key购买 nike

我有这样的课:

//Array of Structures
class Unit
{
public:
float v;
float u;
//And similarly many other variables of float type, upto 10-12 of them.
void update()
{
v+=u;
v=v*i*t;
//And many other equations
}
};

我创建了一个 Unit 类型的对象数组。并对它们进行更新。

int NUM_UNITS = 10000;
void ProcessUpdate()
{
Unit *units = new Unit[NUM_UNITS];
for(int i = 0; i < NUM_UNITS; i++)
{
units[i].update();
}
}

为了加快速度,并可能自动矢量化循环,我将 AoS 转换为数组结构。

//Structure of Arrays:
class Unit
{
public:
Unit(int NUM_UNITS)
{
v = new float[NUM_UNITS];
}
float *v;
float *u;
//Mnay other variables
void update()
{
for(int i = 0; i < NUM_UNITS; i++)
{
v[i]+=u[i];
//Many other equations
}
}
};

当循环无法自动矢量化时,数组结构的性能非常差。对于 50 个单元,SoA 的更新比 AoS 稍快。但是从 100 个单元开始,SoA 比 AoS 慢。在 300 个单位时,SoA 几乎差一倍。在 100K 单位时,SoA 比 AoS 慢 4 倍。虽然缓存可能是 SoA 的一个问题,但我没想到性能差异会如此之大。对 cachegrind 的分析显示两种方法的未命中次数相似。 Unit 对象的大小为 48 字节。 L1 缓存为 256K,L2 为 1MB,L3 为 8MB。我在这里想念什么?这真的是缓存问题吗?

编辑:我正在使用 gcc 4.5.2。编译器选项是 -o3 -msse4 -ftree-vectorize。

我在 SoA 中做了另一个实验。我没有动态分配数组,而是在编译时分配了“v”和“u”。当有 100K 个单元时,这提供了比具有动态分配阵列的 SoA 快 10 倍的性能。这里发生了什么事?为什么静态分配的内存和动态分配的内存会有这么大的性能差异?

最佳答案

在这种情况下,数组结构对缓存不友好。

您同时使用 uv,但是如果它们有 2 个不同的数组,它们将不会同时加载到一个缓存行中,并且缓存未命中将花费巨大性能损失。

_mm_prefetch可用于使 AoS 表示更快。

关于c++ - 数组结构和结构数组 - 性能差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11616941/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com