From 92d03f38328f20ce581395fa180d410a9654fa73 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 23 Apr 2024 19:43:08 +0200 Subject: [PATCH] Trivially optimize iteration order in loops Due to how node data is stored iterating X last provides better cache locality. --- src/collision.cpp | 4 ++-- src/environment.cpp | 4 ++-- src/serverenvironment.cpp | 46 +++++++++++++++++++-------------------- src/voxelalgorithms.cpp | 19 +++++++--------- 4 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/collision.cpp b/src/collision.cpp index d12a84f48..2fe209586 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -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); diff --git a/src/environment.cpp b/src/environment.cpp index 44ab8a6bf..011534e00 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -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; diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 8a7b568eb..423f51b40 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -266,29 +266,29 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block, content_t previous_c = CONTENT_IGNORE; const std::vector *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.XgetNodeNoCheck(p0); content_t c = n.getContent(); diff --git a/src/voxelalgorithms.cpp b/src/voxelalgorithms.cpp index bd155a7e7..f0b07c814 100644 --- a/src/voxelalgorithms.cpp +++ b/src/voxelalgorithms.cpp @@ -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 &lights = light_sources.lights[i]; - for (std::vector::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 &lights = light_sources.lights[i]; - for (std::vector::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 &lights = relight[b].lights[i]; - for (std::vector::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