Memory mappings
One we have the capability to get memory we must map that structure into memory. There are three specific factor that regulate this
- Linearisation (1D transformation)
- Basic object
- Implementation
While the basic structure can be analysed in order to choose the best format (in case of the use of format 2), the other degree of freedom can be implemented as template parameters in your basic structure, in order to give flexibility to your structure.
One example is grid,
template<unsigned int dim, typename T, typename Mem = typename memory_traits_lin< typename T::type >::type , grid_ind=grid_sm<dim>>
class grid_cpu
{
A grid has a natural indexing based on k-indexes with k == dimensionality of the grid, the last template argument, grid_ind=grid_sm, with the class grid_sm give specify a linearisation (map) of the indexes. The class grid_sm implement the typical linearisation of the indexes by stride with last index as the lower index (C ordering), others map implementations can produce strides with first index as lower index (Fortran ordering), or implementing other maps like Hilbert curves for cache friendlyness, other space filling curves or even other more complex mappings that can involve sparse rappresentation/multi-resolution.
The definition of a linearisation is required only for structure with random access capabilities.
id = LinId(key)
Where for example the key in case of the grid is a set of indexes ( aka grid_key_dx ) and it encapsulate a static array with k indexes "mem_id[k]" (aka long int[k])