在游戏引擎开发中,我们通常使用面向数据的设计来获得最佳的内存和计算性能.
我们以粒子系统为例.
在粒子系统中,我们有很多粒子,每个粒子可能有几个属性,如位置,速度等.
C++中的典型实现如下:
struct Particle {
float positionX, positionY, positionZ;
float velocityX, velocityY, velocityZ;
float mass;
// ...
};
struct ParticleSystem {
vector<Particle> particles;
// ...
};
Run Code Online (Sandbox Code Playgroud)
该实现的一个问题是粒子属性彼此交错.此内存布局不是缓存友好的,可能不适合SIMD计算.
而是在面向数据的设计中,我们编写以下代码:
struct ParticleAttribute {
size_t size;
size_t alignment;
const char* semantic;
};
struct ParticleSystem {
ParticleSystem(
size_t numParticles,
const ParticleAttribute* attributes,
size_t bufferSize) {
for (size_t i = 0; i < numAttributes; ++i) {
bufferSize += attributes[i].size * numParticles;
// Also add paddings to satisfy the alignment requirements.
}
particleBuffer …Run Code Online (Sandbox Code Playgroud) 我知道我可以在EngineBuilder中设置mcpu和mattr来生成矢量化代码.但我发现clang前端必须涉及使用-mavx的AVX.否则生成的程序集仅使用xmm寄存器.
有没有办法让LLVM知道8个浮点数可以放在AVX寄存器中而不涉及前端?
我的测试代码只是向量添加:
float a[N], b[N];
float c[N];
// initialize a and b
for (int i = 0; i < N; ++i)
c[i] = a[i] + b[i];
Run Code Online (Sandbox Code Playgroud)