I began this week by analysing the source code provided with GPU Gems 2 to try and understand the GPU implementation of the reaction diffusion algorithm. Unfortunately I found this task to be gargantuan, a large percentage of the considerable amount of source code was more related to the operation of the underlying framework and the diffusion algorithm seemed to be unhelpfully split across many long and opaque functions. After a few hours trying to understand the operation of the algorithm as described here I decided to look elsewhere.
I realised upon looking further afield that nearly all implementations of this have been created for GPUs. It makes sense as this algorithm is perfect for performing in parallel on a texture, which makes a CPU implementation not particularly worthwhile. However, my aim is not to improve on the simulation using SpatialOS, my aim is to use a simulation to identify performance bottlenecks of SpatialOS and how these can be designed around.
I decided to write my own implementation of the algorithm using the equations and descriptions provided here. As I would not be relying on any kind of global manager and have all bodies self-managing, I would need to create a neighbour searching algorithm which would identify the physical neighbours of the cells. This initially began as 8 raycasts aligned to the compass points to detect neighbours. This was an extremely expensive operation to perform each frame and so I redesigned the neighbour searching to use a sphere cast. This improved the performance considerably, although it is still by far the least performant part of the simulation.
In general, the algorithm was relatively straight forward to implement. I created this just in a blank unity project as I wanted to be sure the simulation behaved as expected without the complication of SpatialOS. The result is very slow, however, being unable to compute many cells. Especially compared to the possibility of using a texture on a GPU to perform the same function. The biggest bottleneck, as described above, is the neighbour searching.
Above I have my algorithm where da is the diffusion rate of chemical a and db is the diffusion rate of chemical b. Additionally k is the kill rate and f is the feed rate.
Hopefully by putting this algorithm onto the cloud, with multiple workers managing the simulation, the performance can be significantly improved.