Trivially optimize iteration order in loops

Due to how node data is stored iterating X last provides better cache locality.
This commit is contained in:
sfan5 2024-04-23 19:43:08 +02:00
parent 2efd0996e6
commit 92d03f3832
4 changed files with 35 additions and 38 deletions

View File

@ -291,9 +291,9 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
bool any_position_valid = false;
v3s16 p;
for (p.X = min.X; p.X <= max.X; p.X++)
for (p.Z = min.Z; p.Z <= max.Z; p.Z++)
for (p.Y = min.Y; p.Y <= max.Y; p.Y++)
for (p.Z = min.Z; p.Z <= max.Z; p.Z++) {
for (p.X = min.X; p.X <= max.X; p.X++) {
bool is_position_valid;
MapNode n = map->getNode(p, &is_position_valid);

View File

@ -185,9 +185,9 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result_p)
}
// For each untested node
for (s16 x = new_nodes.MinEdge.X; x <= new_nodes.MaxEdge.X; x++)
for (s16 z = new_nodes.MinEdge.Z; z <= new_nodes.MaxEdge.Z; z++)
for (s16 y = new_nodes.MinEdge.Y; y <= new_nodes.MaxEdge.Y; y++)
for (s16 z = new_nodes.MinEdge.Z; z <= new_nodes.MaxEdge.Z; z++) {
for (s16 x = new_nodes.MinEdge.X; x <= new_nodes.MaxEdge.X; x++) {
MapNode n;
v3s16 np(x, y, z);
bool is_valid_position;

View File

@ -266,29 +266,29 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block,
content_t previous_c = CONTENT_IGNORE;
const std::vector<LoadingBlockModifierDef *> *lbm_list = nullptr;
for (pos.X = 0; pos.X < MAP_BLOCKSIZE; pos.X++)
for (pos.Y = 0; pos.Y < MAP_BLOCKSIZE; pos.Y++)
for (pos.Z = 0; pos.Z < MAP_BLOCKSIZE; pos.Z++) {
n = block->getNodeNoCheck(pos);
c = n.getContent();
for (pos.Z = 0; pos.Z < MAP_BLOCKSIZE; pos.Z++)
for (pos.Y = 0; pos.Y < MAP_BLOCKSIZE; pos.Y++)
for (pos.X = 0; pos.X < MAP_BLOCKSIZE; pos.X++) {
n = block->getNodeNoCheck(pos);
c = n.getContent();
// If content_t are not matching perform an LBM lookup
if (previous_c != c) {
lbm_list = it->second.lookup(c);
previous_c = c;
}
// If content_t are not matching perform an LBM lookup
if (previous_c != c) {
lbm_list = it->second.lookup(c);
previous_c = c;
}
if (!lbm_list)
continue;
for (auto lbmdef : *lbm_list) {
lbmdef->trigger(env, pos + pos_of_block, n, dtime_s);
if (block->isOrphan())
return;
n = block->getNodeNoCheck(pos);
if (n.getContent() != c)
break; // The node was changed and the LBMs no longer apply
}
}
if (!lbm_list)
continue;
for (auto lbmdef : *lbm_list) {
lbmdef->trigger(env, pos + pos_of_block, n, dtime_s);
if (block->isOrphan())
return;
n = block->getNodeNoCheck(pos);
if (n.getContent() != c)
break; // The node was changed and the LBMs no longer apply
}
}
}
}
@ -935,9 +935,9 @@ public:
bool want_contents_cached = block->contents.empty() && !block->do_not_cache_contents;
v3s16 p0;
for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
for(p0.Y=0; p0.Y<MAP_BLOCKSIZE; p0.Y++)
for(p0.Z=0; p0.Z<MAP_BLOCKSIZE; p0.Z++)
for(p0.Y=0; p0.Y<MAP_BLOCKSIZE; p0.Y++)
for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
{
MapNode n = block->getNodeNoCheck(p0);
content_t c = n.getContent();

View File

@ -618,9 +618,8 @@ void update_lighting_nodes(Map *map,
modified_blocks);
// Initialize light values for light spreading.
for (u8 i = 0; i <= LIGHT_SUN; i++) {
const std::vector<ChangingLight> &lights = light_sources.lights[i];
for (std::vector<ChangingLight>::const_iterator it = lights.begin();
it < lights.end(); ++it) {
const auto &lights = light_sources.lights[i];
for (auto it = lights.begin(); it < lights.end(); ++it) {
MapNode n = it->block->getNodeNoCheck(it->rel_position);
n.setLight(bank, i, ndef->getLightingFlags(n));
it->block->setNodeNoCheck(it->rel_position, n);
@ -737,9 +736,8 @@ void update_block_border_lighting(Map *map, MapBlock *block,
modified_blocks);
// Initialize light values for light spreading.
for (u8 i = 0; i <= LIGHT_SUN; i++) {
const std::vector<ChangingLight> &lights = light_sources.lights[i];
for (std::vector<ChangingLight>::const_iterator it = lights.begin();
it < lights.end(); ++it) {
const auto &lights = light_sources.lights[i];
for (auto it = lights.begin(); it < lights.end(); ++it) {
MapNode n = it->block->getNodeNoCheck(it->rel_position);
n.setLight(bank, i, ndef->getLightingFlags(n));
it->block->setNodeNoCheck(it->rel_position, n);
@ -984,8 +982,8 @@ void finish_bulk_light_update(Map *map, mapblock_v3 minblock,
// Skip not existing blocks
continue;
// For each node in the block:
for (relpos.X = 0; relpos.X < MAP_BLOCKSIZE; relpos.X++)
for (relpos.Z = 0; relpos.Z < MAP_BLOCKSIZE; relpos.Z++)
for (relpos.X = 0; relpos.X < MAP_BLOCKSIZE; relpos.X++)
for (relpos.Y = 0; relpos.Y < MAP_BLOCKSIZE; relpos.Y++) {
MapNode node = block->getNodeNoCheck(relpos.X, relpos.Y, relpos.Z);
ContentLightingFlags f = ndef->getLightingFlags(node);
@ -1011,9 +1009,8 @@ void finish_bulk_light_update(Map *map, mapblock_v3 minblock,
u8 maxlight = (b == 0) ? LIGHT_MAX : LIGHT_SUN;
// Initialize light values for light spreading.
for (u8 i = 0; i <= maxlight; i++) {
const std::vector<ChangingLight> &lights = relight[b].lights[i];
for (std::vector<ChangingLight>::const_iterator it = lights.begin();
it < lights.end(); ++it) {
const auto &lights = relight[b].lights[i];
for (auto it = lights.begin(); it < lights.end(); ++it) {
MapNode n = it->block->getNodeNoCheck(it->rel_position);
n.setLight(bank, i, ndef->getLightingFlags(n));
it->block->setNodeNoCheck(it->rel_position, n);
@ -1085,8 +1082,8 @@ void blit_back_with_light(Map *map, MMVManip *vm,
// For each border of the block:
for (const VoxelArea &a : block_pad) {
// For each node of the border:
for (relpos.X = a.MinEdge.X; relpos.X <= a.MaxEdge.X; relpos.X++)
for (relpos.Z = a.MinEdge.Z; relpos.Z <= a.MaxEdge.Z; relpos.Z++)
for (relpos.X = a.MinEdge.X; relpos.X <= a.MaxEdge.X; relpos.X++)
for (relpos.Y = a.MinEdge.Y; relpos.Y <= a.MaxEdge.Y; relpos.Y++) {
// Get old and new node