<Nexus>
Traveler of the Multiverse
So what is ID allocation limit? Can it be increased?
8K.So what is ID allocation limit? Can it be increased?
#define FLTA_ID_SHIFT (13)
#define FLTA_MAX_BUCKETS (1 << FLTA_ID_SHIFT)
AI_updateRouteToCity
are next, but getting mid-game turn times under control is not going to be possible for 10x Huge. The AI stuff will just need a whole rework. Or I extend the parallel unit update implementation to cover most AI, but... ehh... Maybe I should just find the biggest playable map size that doesn't require herculean parallel AI efforts.Wow! That's a lot. I guess we run out of city names much earlier.
Just wanted to ask about that.Maybe I should just find the biggest playable map size that doesn't require herculean parallel AI efforts.
/* advc.opt: In a test over a few turns on a Giant map with 36 civs,
the mean list size at the start of processNode was 80, and the
maximal list size 333. In a longer test on a Huge map with 18 civs,
reserving memory for 128 nodes was faster than for either 32, 200 or 256
(power of 2 does seem to help). K-Mod didn't reserve any memory. */
/* ^Looks like K-Mod has already tried a heap (std: priority_queue). Or maybe
it was abandoned w/o a test. Would have to re-heap after recalculateHeuristics.
And the functor should take m_stepMetric.getMaxPath() as a contructor argument
so that nodes within that limit can receive absolute priority. But, given the
modest number of open nodes, I doubt that a heap will be worthwhile. */
The nerdy stuff. Open set size goes up to around 2300 for 1040x640 on turn 520. I have tried different types of heaps. Currently using a quaternary heap in an array. Popping is the problem, so I think it's slow because it has to bubble down an element from the top to the bottom. And it does it for each active element in the SIMD vector.Let me start out by saying that I’m very impressed by your efforts and skill.
... before diving straight into the nerdy stuff:
What are the average- and worst-case sizes of your open list?
I’m asking because the K-Mod Pathfinder (refactored and improved by @f1rpo for the Advanced Civ Mod: https://github.com/f1rpo/AdvCiv/blob/1.12/CvGameCoreDLL/KmodPathFinder.h
) stores its open list in a std::vector. That means that the two (or three depending on your viewpoint) critical open list operations have the complexity:
1) Finding the minimum element requires a linear scan (O(n)). Quite a bit worse than the heap but extremely cache friendly.
2) Appending a new element is a constant-time push_back (O(1)).
3) Removing an element is just swapping with and popping the last element (ok since the list is not ordered and we're already committed to a linear scan)
I'm curious what numbers you are seeing. Also note this comment:
However, it very likely that you are seeing much worse numbers considering your 1000x1000 map! Still it would be interesting to know the inflection point of a heap vs. a vector with respect to the open list.
See this as well
Finally, the linear find-min scan could itself be sped up by using branchless AVX2 code, effectively pushing the heap-vs-vector inflection point even higher. Have you (or anyone) actually measured where that sweet spot lies?
CvPlotGroup::recalculatePlots
has started to show up on the profiler, at about 55% CPU time on the main thread. Turn times are reaching ~20s at turn 536.Limit!? Maybe there could be a warning message.Maybe limit the game to a map size that won't exceed the limits?
co_await
updated pathfinding plot info when a pending plot shows up at the top of the open set. This may be insanely complex to implement.But to Firaxis' credit, they did try local updates. But in the case of disconnect, it may recount all plots in the group. And that group might include the whole ocean, I assume.if i could suggest one thing that may need to be murdered, dissected and rebuilt, it's the plotgroup system (which is the system handling which tiles are connected for resource access and trade purposes).
From what i've had to interact with, it seems very innefficient, with groups being completely deleted and rebuilt tile by tile each time there's an effect that impacts it ( pillaged road or improvement, discovered resources, ....)
(storage of the network is the key part to make that work, as of now, it's just a list of all the tiles in the group, without better understanding of the links between them)
CvPlotGroup
will store a list of block plot group indices. But, you'd still need to loop over plots in case of split/join, to call CvPlot::setPlotGroup
. This could possibly be threaded. Or further accelerated by counting bonuses block-wise (so, plots would have a CvBlockPlotGroup*
and that will have a CvPlotGroup*
).CvCity::changeNumBonuses
has complex logic that can't just be refactored away. Mechanical redesign though could do all city bonus updates during a single parallel city update, maybe, possibly. At least for AI, things that invalidate plot groups and things that depend on city bonuses could be separated within the turn.