所以我有一个结构数组:
typedef struct {
float x;
float y;
float z;
} Point;
const int SIZE = 16;
Point* points;
points = malloc(SIZE * sizeof(Point));
现在我还有一个数组结构:
typedef struct {
float* vectorX;
float* vectorY;
float* vectorZ;
} arrayStruct;
arrayStruct myArrayStruct;
// Allocate Memory
myArrayStruct.vectorX = _aligned_malloc(sizeof(float)* SIZE, 32);
myArrayStruct.vectorY = _aligned_malloc(sizeof(float)* SIZE, 32);
myArrayStruct.vectorZ = _aligned_malloc(sizeof(float)* SIZE, 32);
所以现在我的问题是: 是否有快速/简单的方法使用SIMD(内部函数)将AoS(结构数组)转换为数组结构?
答案 0 :(得分:4)
您实际上没有指定要使用的指令集,所以这是一个SSE4实现。无论您使用的是SSE / AVX2 / AVX512,基本上都可以利用一系列混合和随机播放操作(以及AVX +的一些其他128位排列)。 Blend和Shuffle的等待时间均为1,吞吐量为0.33,因此应满足“快速”要求。因此,以AOS格式的4xVec3开始:
r0 = [x0 y0 z0 x1]
r1 = [y1 z1 x2 y2]
r2 = [z2 x3 y3 z3]
您应该可以按照以下方式进行操作:
template<bool c0, bool c1, bool c2, bool c3>
inline f128 blend4f(const f128 tr, const f128 fr)
{ return _mm_blend_ps(fr, tr, (c3 << 3) | (c2 << 2) | (c1 << 1) | c0); }
template<uint8_t X, uint8_t Y, uint8_t Z, uint8_t W>
inline f128 shuffle4f(const f128 a, const f128 b)
{ return _mm_shuffle_ps(a, b, _MM_SHUFFLE(W, Z, Y, X)); }
inline void vec3_aos2_soa(
const f128 r0, const f128 r1, const f128 r2,
f128& x, f128& y, f128& z)
{
x = blend4f<1, 0, 0, 1>(r0, r1); // x0 z1 x2 x1
y = blend4f<1, 0, 0, 1>(r1, r2); // y1 x3 y3 y2
z = blend4f<1, 0, 0, 1>(r2, r0); // z2 y0 z0 z3
x = blend4f<1, 0, 1, 1>(x, r2); // x0 x3 x2 x1
y = blend4f<1, 0, 1, 1>(y, r0); // y1 y0 y3 y2
z = blend4f<1, 0, 1, 1>(z, r1); // z2 z1 z0 z3
x = shuffle4f<0, 3, 2, 1>(x, x); // x0 x1 x2 x3
y = shuffle4f<1, 0, 3, 2>(y, y); // y0 y1 y2 y3
z = shuffle4f<2, 1, 0, 3>(z, z); // z0 z1 z2 z3
}
要以其他方式返回,请随机播放,然后融合回到起点。