subdgtl / WFC

Prototype tools for playing with Wave Function Collapse
The Unlicense
5 stars 1 forks source link

Change internal world representation to be const-parametrizable for different module counts #24

Closed yanchith closed 3 years ago

yanchith commented 3 years ago

Allows us to scale number of supported modules, both down and up (within reason). Scaling up allows us to simply support more modules, currently up to 1014. By scaling down we get speed improvements (because of less copying of data and maybe better cache locality).

Implemented by making BitVec generic over N: usize - the block count. This generic parameter also infects the world, but to stop the cascade we add a few pre-generated variants which we switch dynamically on the perimeter. Hot sections of code should still be monomorphic as before.

Preliminary benchmarks show no degradation of performance for 4-block bit vectors (4 is the only block count we supported previously), and a 35% time improvement if we only use 1-block bit vectors.

TODO:

yanchith commented 3 years ago

Thx for looking at this! I'll do one more self-review tomorrow. I'd like to investigate why this is so slow in GH (but not outside of GH). I hope this is not caused by the more granular getter/setter functions.

Also, I am considering moving the world status in wfc_world_state_canonicalize and wfc_observe to an out param. wfc_world_state_canonicalize will have no result type, and wfc_observe will just have Ok and ErrNotCanonical.

janper commented 3 years ago

I'd like to investigate why this is so slow in GH (but not outside of GH). I hope this is not caused by the more granular getter/setter functions.

McNeel offers free support for plugin developers. I was thinking of putting together a list of questions and this could be one of them.

yanchith commented 3 years ago

@janper I am done with my testing. Feel free to try and integrate into Monoceros. I'll keep this PR open as a place where we can discuss integration issues.

While I did some testing, I didn't have time to build a serious integration test. There still may be serious bugs lurking around (e.g. I didn't test weights at all), so feel free to report problems and ask questions.

One thing I've noticed that data import and export may have gotten slower with the new API. For small worlds with many modules, getting the data in and out of the DLL takes longer than observing the world. This problem should fade to the background once the solution needs multiple attempts, but I have an idea how to improve some of this in the future without much work.

Regarding the component times reported by the GH profilers, it turns out that it only runs that long for the first time, and then times actually correspond to what the C# stopwatch says, even if GH still reports the long times.