1
0
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:
Michał Janiszewski
2017-07-18 15:18:15 +02:00
committed by Michael Steenbeek
parent eeeebe5525
commit fc59fc7573

View File

@@ -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;