class Particle {
Vec3 position;
Vec3 velocity;
Color color;
void update() {
position.x += velocity.x;
position.y += velocity.y;
position.z += velocity.z;
}
void render(GraphicsContext& ctx) {
//...
}
};
class Particle {
Vec3 position;
Vec3 velocity;
Color color; <---- Cached but unused in update()
void update() { <---- Potential i-cache miss per particle
position.x += velocity.x; <---
position.y += velocity.y; <--- Potential data misses
position.z += velocity.z; <---
}
void render(GraphicsContext& ctx) {
//...
}
};
void update() {
position.x += velocity.x;
position.y += velocity.y;
position.z += velocity.z;
}
class ParticleManager {
std::vector<Vec3> positions; <--- Data is stored sequentially,
std::vector<Vec3> velocities; <--- not in bits and pieces all
std::vector<Color> colors; <--- over the heap
void update() { <---- Reduce number of i-cache misses to at most 1
for (int i = 0; i < positions.size(); i++){
positions[i].x += velocities[i].x; <-- Read data sequentially
positions[i].y += velocities[i].y; <-- to minimize the number
positions[i].z += velocities[i].z; <-- of data cache misses
}
}
};
struct ParticleMotionData {
Vec3 position;
Vec3 velocity;
};
class ParticleManager {
std::vector<ParticleMotionData> motion; <-- Stored together now
std::vector<Color> colors;
void update() {
for (int i = 0; i < motion.size(); i++) {
motion[i].position.x += motion[i].velocity.x;
motion[i].position.y += motion[i].velocity.y;
motion[i].position.z += motion[i].velocity.z;
}
}
};