Multidimensional Arrays and std::mdspan

Layout Mapping in mdspan

What is the purpose of the layout mapping policy in mdspan?

Abstract art representing computer programming

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:

Flexibility in Memory Layout

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:

  • Row-major layout: Elements are stored in memory row by row. This is the default layout mapping policy used by std::mdspan if not explicitly specified.
  • Column-major layout: Elements are stored in memory column by column. This layout is commonly used in languages like Fortran and can be beneficial for certain mathematical operations.
  • Strided layout: Elements are stored with specific strides (offsets) between dimensions. This allows for more control over the memory layout and can be useful for interoperability with external libraries or APIs.

Performance Optimization

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.

Interoperability with Existing Code

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.

Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved