forked from Mirrorlandia_minetest/minetest
Reorder members of MapBlock for performance
Before and after as obtained via `pahole -C MapBlock bin/minetest`: /* size: 336, cachelines: 6, members: 23 */ /* sum members: 329, holes: 4, sum holes: 7 */ vs. /* size: 336, cachelines: 6, members: 23 */ /* sum members: 329, holes: 2, sum holes: 7 */ There is not much to be gained by packing but I made sure to move the most important data (mainly for the client) into the first cache line.
This commit is contained in:
parent
9408a1a025
commit
128ed87dd8
126
src/mapblock.h
126
src/mapblock.h
@ -437,6 +437,11 @@ public:
|
|||||||
// clearObject and return removed objects count
|
// clearObject and return removed objects count
|
||||||
u32 clearObjects();
|
u32 clearObjects();
|
||||||
|
|
||||||
|
static const u32 ystride = MAP_BLOCKSIZE;
|
||||||
|
static const u32 zstride = MAP_BLOCKSIZE * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
|
static const u32 nodecount = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
Private methods
|
Private methods
|
||||||
@ -444,59 +449,73 @@ private:
|
|||||||
|
|
||||||
void deSerialize_pre22(std::istream &is, u8 version, bool disk);
|
void deSerialize_pre22(std::istream &is, u8 version, bool disk);
|
||||||
|
|
||||||
public:
|
|
||||||
/*
|
/*
|
||||||
Public member variables
|
* PLEASE NOTE: When adding something here be mindful of position and size
|
||||||
*/
|
* of member variables! This is also the reason for the weird public-private
|
||||||
|
* interleaving.
|
||||||
|
* If in doubt consult `pahole` to see the effects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public:
|
||||||
#ifndef SERVER // Only on client
|
#ifndef SERVER // Only on client
|
||||||
MapBlockMesh *mesh = nullptr;
|
MapBlockMesh *mesh = nullptr;
|
||||||
|
|
||||||
|
// marks the sides which are opaque: 00+Z-Z+Y-Y+X-X
|
||||||
|
u8 solid_sides = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NodeMetadataList m_node_metadata;
|
|
||||||
StaticObjectList m_static_objects;
|
|
||||||
|
|
||||||
static const u32 ystride = MAP_BLOCKSIZE;
|
|
||||||
static const u32 zstride = MAP_BLOCKSIZE * MAP_BLOCKSIZE;
|
|
||||||
|
|
||||||
static const u32 nodecount = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
|
|
||||||
|
|
||||||
//// ABM optimizations ////
|
|
||||||
// Cache of content types
|
|
||||||
// This is actually a set but for the small sizes we have a vector should be
|
|
||||||
// more efficient.
|
|
||||||
// Can be empty, in which case nothing was cached yet.
|
|
||||||
std::vector<content_t> contents;
|
|
||||||
// True if we never want to cache content types for this block
|
|
||||||
bool do_not_cache_contents = false;
|
|
||||||
// marks the sides which are opaque: 00+Z-Z+Y-Y+X-X
|
|
||||||
u8 solid_sides {0};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
// see isOrphan()
|
||||||
Private member variables
|
bool m_orphan = false;
|
||||||
*/
|
|
||||||
|
|
||||||
// Position in blocks on parent
|
// Position in blocks on parent
|
||||||
v3s16 m_pos;
|
v3s16 m_pos;
|
||||||
|
|
||||||
/* This is the precalculated m_pos_relative value
|
/* Precalculated m_pos_relative value
|
||||||
* This caches the value, improving performance by removing 3 s16 multiplications
|
* This caches the value, improving performance by removing 3 s16 multiplications
|
||||||
* at runtime on each getPosRelative call
|
* at runtime on each getPosRelative call.
|
||||||
* For a 5 minutes runtime with valgrind this removes 3 * 19M s16 multiplications
|
* For a 5 minutes runtime with valgrind this removes 3 * 19M s16 multiplications.
|
||||||
* The gain can be estimated in Release Build to 3 * 100M multiply operations for 5 mins
|
* The gain can be estimated in Release Build to 3 * 100M multiply operations for 5 mins.
|
||||||
*/
|
*/
|
||||||
v3s16 m_pos_relative;
|
v3s16 m_pos_relative;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that this is not an inline array because that has implications on
|
Reference count; currently used for determining if this block is in
|
||||||
|
the list of blocks to be drawn.
|
||||||
|
*/
|
||||||
|
short m_refcount = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that this is not an inline array because that has implications for
|
||||||
* heap fragmentation (the array is exactly 16K), CPU caches and/or
|
* heap fragmentation (the array is exactly 16K), CPU caches and/or
|
||||||
* optimizability of algorithms working on this array.
|
* optimizability of algorithms working on this array.
|
||||||
*/
|
*/
|
||||||
MapNode *const data; // of `nodecount` elements
|
MapNode *const data; // of `nodecount` elements
|
||||||
|
|
||||||
|
// provides the item and node definitions
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
|
|
||||||
|
/*
|
||||||
|
When the block is accessed, this is set to 0.
|
||||||
|
Map will unload the block when this reaches a timeout.
|
||||||
|
*/
|
||||||
|
float m_usage_timer = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//// ABM optimizations ////
|
||||||
|
// True if we never want to cache content types for this block
|
||||||
|
bool do_not_cache_contents = false;
|
||||||
|
// Cache of content types
|
||||||
|
// This is actually a set but for the small sizes we have a vector should be
|
||||||
|
// more efficient.
|
||||||
|
// Can be empty, in which case nothing was cached yet.
|
||||||
|
std::vector<content_t> contents;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Whether day and night lighting differs
|
||||||
|
bool m_day_night_differs = false;
|
||||||
|
bool m_day_night_differs_expired = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
- On the server, this is used for telling whether the
|
- On the server, this is used for telling whether the
|
||||||
block has been modified from the one on disk.
|
block has been modified from the one on disk.
|
||||||
@ -506,14 +525,12 @@ private:
|
|||||||
u32 m_modified_reason = MOD_REASON_INITIAL;
|
u32 m_modified_reason = MOD_REASON_INITIAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When propagating sunlight and the above block doesn't exist,
|
When block is removed from active blocks, this is set to gametime.
|
||||||
sunlight is assumed if this is false.
|
Value BLOCK_TIMESTAMP_UNDEFINED=0xffffffff means there is no timestamp.
|
||||||
|
|
||||||
In practice this is set to true if the block is completely
|
|
||||||
undeground with nothing visible above the ground except
|
|
||||||
caves.
|
|
||||||
*/
|
*/
|
||||||
bool is_underground = false;
|
u32 m_timestamp = BLOCK_TIMESTAMP_UNDEFINED;
|
||||||
|
// The on-disk (or to-be on-disk) timestamp value
|
||||||
|
u32 m_disk_timestamp = BLOCK_TIMESTAMP_UNDEFINED;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Each bit indicates if light spreading was finished
|
* Each bit indicates if light spreading was finished
|
||||||
@ -525,35 +542,24 @@ private:
|
|||||||
*/
|
*/
|
||||||
u16 m_lighting_complete = 0xFFFF;
|
u16 m_lighting_complete = 0xFFFF;
|
||||||
|
|
||||||
// Whether day and night lighting differs
|
|
||||||
bool m_day_night_differs = false;
|
|
||||||
bool m_day_night_differs_expired = true;
|
|
||||||
|
|
||||||
// see isOrphan()
|
|
||||||
bool m_orphan = false;
|
|
||||||
// Whether mapgen has generated the content of this block (persisted)
|
// Whether mapgen has generated the content of this block (persisted)
|
||||||
bool m_generated = false;
|
bool m_generated = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When block is removed from active blocks, this is set to gametime.
|
When propagating sunlight and the above block doesn't exist,
|
||||||
Value BLOCK_TIMESTAMP_UNDEFINED=0xffffffff means there is no timestamp.
|
sunlight is assumed if this is false.
|
||||||
*/
|
|
||||||
u32 m_timestamp = BLOCK_TIMESTAMP_UNDEFINED;
|
|
||||||
// The on-disk (or to-be on-disk) timestamp value
|
|
||||||
u32 m_disk_timestamp = BLOCK_TIMESTAMP_UNDEFINED;
|
|
||||||
|
|
||||||
/*
|
In practice this is set to true if the block is completely
|
||||||
When the block is accessed, this is set to 0.
|
undeground with nothing visible above the ground except
|
||||||
Map will unload the block when this reaches a timeout.
|
caves.
|
||||||
*/
|
*/
|
||||||
float m_usage_timer = 0;
|
bool is_underground = false;
|
||||||
|
|
||||||
/*
|
public:
|
||||||
Reference count; currently used for determining if this block is in
|
NodeMetadataList m_node_metadata;
|
||||||
the list of blocks to be drawn.
|
StaticObjectList m_static_objects;
|
||||||
*/
|
|
||||||
short m_refcount = 0;
|
|
||||||
|
|
||||||
|
private:
|
||||||
NodeTimerList m_node_timers;
|
NodeTimerList m_node_timers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user