如何判断带步长的多维数组视图是否占用连续内存区域?
4D数组视图结构体定义
我们定义如下结构体(类):
struct Array4DView { float* origin; std::array<int,4> dims, strides; } v;
该结构体以numpy的方式表示多维数组视图(但不拥有v.origin指向的内存):
- 维度大小由
v.dims指定 - 步长由
v.strides指定
要访问索引为(4,6,8,10)的元素,需执行如下操作:
*(v.origin + v.strides[0]*4 + v.strides[1]*6 + v.strides[2]*8 + v.strides[3]*10)
连续视图的定义与示例
我们定义:当且仅当视图的元素占据一块无间隙的连续内存块时,该视图是连续的。
例如:
Array4DView view1 = {some_ptr, {2,3,4,5}, {5*4*3, 5*4, 5, 1}};
此时view1是连续的,且采用C顺序(行主序)。连续视图的优势在于可正确转换为对应的std::span(仅丢失维度信息,保留数据),之后可转换为字节缓冲区写入文件(假设字节序、IEEE浮点支持等无问题)。
非连续视图的场景
该视图可通过对“真正的”多维数组进行切片构建,类似numpy中的操作。例如在Python+numpy代码中:
pyview = pyarr[3:6, 2:8:2]
此时pyview是非连续的,即其元素所在的内存块中存在不属于该视图元素的间隙。
问题:判断视图是否连续的最优算法是什么?
感谢@MattTimmermans提供的正确算法(实现为成员函数):
bool is_continuous() const { std::ptrdiff_t prod = 0; /* 或使用 std::size_t */ for (std::size_t i = 0; i < N; ++i) { prod += (this->dims[i]-1) * std::abs(this->strides[i]); } return prod + 1 == this->num_elements(); }
内容的提问来源于stack exchange,提问作者smitsyn
相关产品推荐
相关产品推荐

