The layout mapping policy in std::mdspan
is an optional template parameter that allows you to customize how the multidimensional indices are mapped to the underlying contiguous memory layout. It determines the order and organization of elements in memory.
The primary purposes of the layout mapping policy are:
Different applications and domains may have different requirements for how multidimensional data is laid out in memory.
The layout mapping policy provides flexibility to choose a memory layout that best suits the specific needs of your application. Some common layout mapping policies include:
std::mdspan
 if not explicitly specified.The choice of layout mapping policy can have an impact on performance, particularly when accessing elements in a specific order or pattern.
For example, if your application frequently accesses elements along a specific dimension (e.g., row-wise or column-wise), choosing a layout mapping policy that aligns with that access pattern can lead to better cache locality and faster memory access.
Different libraries, frameworks, or APIs may expect multidimensional data to be laid out in a specific way.
By using an appropriate layout mapping policy, you can ensure compatibility and seamless integration with existing code. For instance, if you are working with a library that expects data in column-major order, you can use a column-major layout mapping policy in std::mdspan
 to match the expected layout.
Here's an example that demonstrates the difference between row-major and column-major layout mapping policies:
#include <iostream>
#include <mdspan>
int main() {
// Row-major layout (default)
std::mdspan<int, std::extents<
std::size_t, 2, 3>, std::layout_right>
rowMajorSpan{new int[6]{1, 2, 3, 4, 5, 6}};
std::cout << "Row-major layout:\n";
for (std::size_t i = 0;
i < rowMajorSpan.extent(0); ++i) {
for (std::size_t j = 0;
j < rowMajorSpan.extent(1); ++j) {
std::cout << rowMajorSpan[i, j] << " ";
}
std::cout << "\n";
}
// Column-major layout
std::mdspan<int, std::extents<
std::size_t, 2, 3>, std::layout_left>
colMajorSpan{new int[6]{1, 4, 2, 5, 3, 6}};
std::cout << "\nColumn-major layout:\n";
for (std::size_t i = 0;
i < colMajorSpan.extent(0); ++i) {
for (std::size_t j = 0;
j < colMajorSpan.extent(1); ++j) {
std::cout << colMajorSpan[i, j] << " ";
}
std::cout << "\n";
}
}
Row-major layout:
1 2 3
4 5 6
Column-major layout:
1 2 3
4 5 6
In this example, we create two mdspan
objects with different layout mapping policies: std::layout_right
for row-major layout and std::layout_left
for column-major layout.
Notice how the elements are initialized differently for each layout policy to achieve the desired memory layout. The row-major layout stores elements in the order {1, 2, 3, 4, 5, 6}
, while the column-major layout stores elements in the order {1, 4, 2, 5, 3, 6}
.
When accessing elements using the [i, j]
syntax, the layout mapping policy takes care of translating the indices to the appropriate memory locations, resulting in the same logical view of the data regardless of the underlying memory layout.
Answers to questions are automatically generated and may not have been reviewed.
std::mdspan
A guide to std::mdspan
, allowing us to interact with arrays as if they have multiple dimensions