在过去的一年里,我注意到StackOverflow上的一些与C相关的答案提到了mdspan
的--但我从来没有在C代码中真正看到过这些。我试着在我的C++编译器的标准库目录和the C++ coding guidelines中寻找它们--但找不到。我确实找到了std::span
的;我猜它们是相关的--但怎么找到的?这后面的“md”代表什么?
请解释一下这个神秘的实体是关于什么的,以及我什么时候可能想要使用它。
在过去的一年里,我注意到StackOverflow上的一些与C相关的答案提到了mdspan
的--但我从来没有在C代码中真正看到过这些。我试着在我的C++编译器的标准库目录和the C++ coding guidelines中寻找它们--但找不到。我确实找到了std::span
的;我猜它们是相关的--但怎么找到的?这后面的“md”代表什么?
请解释一下这个神秘的实体是关于什么的,以及我什么时候可能想要使用它。
1条答案
按热度按时间ozxc1zmp1#
TL; DR:
mdspan
是std::span
在多个维度上的扩展-具有很多(不可避免的)关于内存布局和访问模式的灵活配置。在你阅读这个答案之前,你应该确保你已经清楚了what a
span
is and what it's used for。现在已经不碍事了:由于mdspan
的可能是相当复杂的野兽(通常是std::span
实现的7倍或更多的源代码),我们将从一个简化的描述开始,并在下面保留高级功能。“是什么?”(简单版)
mdspan<T>
是:1.从字面上看,是一个“multi-dimensional span”(类型为-
T
元素)。std::span<T>
的推广,从一维/线性元素序列到多维。1.内存中
T
类型元素的连续序列的非拥有视图,解释为多维数组。1.基本上只是一个
struct { T * ptr; size_type extents[d]; }
,带有一些方便的方法(在运行时确定d
的尺寸)。mdspan
-解释型布局示意图如果我们有:
字符串
我们可以将
v
的数据视为12个元素的一维数组,类似于其原始定义:型
或2D扩展区阵列2 x 6:
型
或3D阵列2 x 3 x 2:
型
我们也可以把它看作是一个3x 2x2或2x2 x3的数组,或者3x 4等等。
“什么时候用?”
operator[]
时,你从某处得到。因此在上面的例子中,ms3[1, 2, 0]
是11
,ms3[0, 1, 1]
是4
。型
你可以这样写:
型
C完全支持multidimensional arrays..
型
标准化状态
虽然
std::span
在C20中被标准化,但std::mdspan
并没有。然而,它是C23的一部分,几乎已经完成(等待最终投票)。你已经可以使用reference implementation了,它是美国桑迪亚国家实验室"Kokkos performance portability ecosystem"的一部分。
“
mdspan
提供了哪些”额外功能“?”mdspan
实际上有4个模板参数,而不仅仅是元素类型和范围:型
这个答案已经很长了,所以我们不会给予完整的细节,但是:
型
.是一个对应于
dextents<size_t>{ 2, 3, 4 }
的extent对象,但它只在类示例中存储值2
和4
;编译器知道每当使用第二维时它需要插入3
。LayoutPolicy = layout_left
,那么mds[x,y]
就在mds.data[mds.extent(0) * y + x]
,而不是通常的mds.data[mds.extent(1) * x + y]
。mdspan
“重塑”为另一个具有不同尺寸但整体大小相同的mdspan
。mdspan
(例如,取一个矩阵的子矩阵)-结果仍然是mdspan
!.这是因为你可以有一个mdspan
和一个包含这些偏移量的LayoutPolicy
。这个功能在C++23 IIANM中是不可用的。AccessorPolicy
,您可以使mdspan
实际上拥有它们引用的数据,单独或共同。进一步阅读
std::mdspan
proposal,被C++23接受。std::mdspan
pagemdspan
的,由阿什尔马基内利。(some这些例子是从这些来源改编的。