mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Cache last visited node in paint_arrange_structs
This commit caches the last visited node in paint_arrange_structs and in paint_arrange_structs_helper, which allows skipping iterating over long linked lists that don't work well with modern CPU caches. This is especially useful, if the list is walked just to be discarded in the end. This improves performance across the board, the busier the park, the higher performance improvement. I have verified this producing pixel-perfect results with ones before this change by dumping giant screenshot on various parks in all zooms, all rotations. Results collected running before and after this change with `benchgfx` command (https://github.com/OpenRCT2/OpenRCT2/pull/5655) on current title sequence, YMMV. **Park**|**Before**|**After**|**Delta** :-----:|:-----:|:-----:|:-----: Maian\_SOSDragon.sv6|2.80|2.43|-13.2% Maian\_SOSFrosty.sv6|3.53|3.02|-14.4% Maian\_SOSParabola.sv6|4.16|3.45|-17.1% MrB.sv6|5.52|4.52|-18.1% SpacekKing.sv6|8.53|6.52|-23.6% SpacekMaple.sv6|7.18|5.75|-19.9% SpacekMission.sv6|4.41|3.43|-22.2% SpacekParadise.sv6|9.01|6.36|-29.4% SpacekSwimmers.sv6|4.11|2.97|-27.7% Stosky.sv6|3.34|2.36|-29.3% | | | **Average**|**5.26**|**4.08**|**-21.5%**
This commit is contained in:
committed by
Michael Steenbeek
parent
eeeebe5525
commit
fc59fc7573
@@ -732,16 +732,19 @@ void paint_generate_structs(rct_drawpixelinfo * dpi)
|
||||
}
|
||||
}
|
||||
|
||||
static void paint_arrange_structs_helper(paint_struct * ps_next, uint16 ax, uint8 flag)
|
||||
static paint_struct * paint_arrange_structs_helper(paint_struct * ps_next, uint16 ax, uint8 flag)
|
||||
{
|
||||
paint_struct * ps;
|
||||
paint_struct * ps_temp;
|
||||
do {
|
||||
ps = ps_next;
|
||||
ps_next = ps_next->next_quadrant_ps;
|
||||
if (ps_next == NULL) return;
|
||||
if (ps_next == NULL) return ps;
|
||||
} while (ax > ps_next->var_18);
|
||||
|
||||
// Cache the last visited node so we don't have to walk the whole list again
|
||||
paint_struct * ps_cache = ps;
|
||||
|
||||
ps_temp = ps;
|
||||
do {
|
||||
ps = ps->next_quadrant_ps;
|
||||
@@ -763,8 +766,8 @@ static void paint_arrange_structs_helper(paint_struct * ps_next, uint16 ax, uint
|
||||
while (true) {
|
||||
while (true) {
|
||||
ps_next = ps->next_quadrant_ps;
|
||||
if (ps_next == NULL) return;
|
||||
if (ps_next->var_1B & (1 << 7)) return;
|
||||
if (ps_next == NULL) return ps_cache;
|
||||
if (ps_next->var_1B & (1 << 7)) return ps_cache;
|
||||
if (ps_next->var_1B & (1 << 0)) break;
|
||||
ps = ps_next;
|
||||
}
|
||||
@@ -857,11 +860,11 @@ paint_struct paint_arrange_structs()
|
||||
}
|
||||
} while (++quadrantIndex <= _paintQuadrantFrontIndex);
|
||||
|
||||
paint_arrange_structs_helper(&psHead, _paintQuadrantBackIndex & 0xFFFF, 1 << 1);
|
||||
paint_struct * ps_cache = paint_arrange_structs_helper(&psHead, _paintQuadrantBackIndex & 0xFFFF, 1 << 1);
|
||||
|
||||
quadrantIndex = _paintQuadrantBackIndex;
|
||||
while (++quadrantIndex < _paintQuadrantFrontIndex) {
|
||||
paint_arrange_structs_helper(&psHead, quadrantIndex & 0xFFFF, 0);
|
||||
ps_cache = paint_arrange_structs_helper(ps_cache, quadrantIndex & 0xFFFF, 0);
|
||||
}
|
||||
}
|
||||
return psHead;
|
||||
|
||||
Reference in New Issue
Block a user