I'm working on a fluid simulation in C#. Each cycle I need to calculate the velocity of the fluid at discrete points in space. As part of that calculation, I need a few tens of kilobytes for scratch space to hold some double[] arrays (the exact size of the arrays depends on some input data). The arrays are only needed for the duration of the method that uses them, and there are a few different methods that needs scratch space like this.
As I see it, there are a few different solutions for constructing the scratch arrays:
Use 'new' to grab memory from the heap every time the method is called. This is what I was doing at first, however it puts a lot of pressure on the garbage collector, and the few-ms spikes once or twice a second are really annoying.
Have the scratch arrays passed as parameters when calling the methods. Problem is that this forces the user to manage them, including sizing them appropriately, which is a huge pain. And it makes using more or less scratch memory difficult since it changes the API.
Use stackalloc in an unsafe context to allocate the scratch memory from the program stack. This would work just fine, except I'd need to compile with /unsafe and constantly sprinkle unsafe blocks throughout my code, which I'd like to avoid.
Preallocate private arrays once when the program starts up. This is fine except I don't necessarily know the size of the arrays I need until I can look at some of the input data. And it gets really messy since you can't limit the scope of these private variables to just a single method, so they're constantly polluting the namespace. And it scales poorly as the number of methods that need scratch memory increases, since I'm allocating a lot of memory that's only used a fraction of the time.
Create some kind of central pool, and allocate scratch memory arrays from the pool. The main problem with this is that I don't see an easy way to allocate dynamically sized arrays from a central pool. I could use a starting offset and length and have all the scratch memory essentially share a single large array, but I have a lot of existing code that assumes double[]s. And I'd have to be careful to make such a pool thread safe.
...
Does anyone have any experience with a similar problem? Any advice/lessons to offer from the experience?