I am writing a simulation engine consisting of a number of components, each of which operates on a fixed set of shared buffers.
In practice, the simulation will run entirely on the GPU. When developing a component however, it is easier to copy the buffers from the GPU, execute the component on the CPU, and write the updated buffers back, continuing on the GPU. When the component has been fully debugged, it is ported to a GPU kernel.
I want to clean up my code and write an interface to the 'main system' (the bit that maintains the buffers) that the components will use, and this raises the question of how to present the buffers.
I could write something like:
interface ISystem
{
Array x;
Array y;
ComputeBuffer gpu_x;
ComputeBuffer gpu_y;
int numElements;
}
But this is not very neat.
I could do something like:
interface ISystem
{
IBuffer x;
IBuffer y;
int numElements;
}
Where IBuffer is an interface suitable for use by code that wants CPU access to the buffer, but also that which binds the buffer to its GPU kernels.
My question is, how far should I push this abstraction?
I could make a truly polymorphic object like:
class BufferHelper<T>
{
static implicit operator ComputeBuffer(BufferHelper helper);
static implicit operator T[](BufferHelper helper);
}
Reading back to the CPU has significant performance implications. However, anyone who will write components will know this, and it will be obvious that this occurs, and where, from the profiler.
From a performance point of view then, there is no benefit to code self-documenting by having explicit interfaces for the two uses of the buffer, but still my instincts say that something is not right with this design.
In the traditional example of polymorphism you'd, say, add two integers or concatenate two strings; operations which are analogous if not identical.
In the above case, the operations (binding a buffer vs. reading it back and modifying it) are completely different.
To put it another way, does this use of polymorphism go so far as to decrease readability and maintainability of the code by hiding things the developer should see?