处理特征中两种存储布局的固定大小矩阵的连续向量
Dealing with a contiguous vector of fixed-size matrices for both storage layouts in Eigen
外部库为我提供了一个原始指针,其中包含要映射到特征类型的double
s。从逻辑上讲,原始数组是小型密集固定大小矩阵的大有序集合,所有矩阵的大小都相同。主要问题是小的密集矩阵可能是行主排序或列主排序,我想同时容纳它们。
我目前的做法如下。请注意,小型固定大小块(在块数组中(的所有条目都需要在内存中连续。
template<int bs, class Mattype>
void block_operation(double *const vals, const int numblocks)
{
Eigen::Map<Mattype> mappedvals(vals,
Mattype::IsRowMajor ? numblocks*bs : bs,
Mattype::IsRowMajor ? bs : numblocks*bs
);
for(int i = 0; i < numblocks; i++)
if(Mattype::isRowMajor)
mappedvals.template block<bs,bs>(i*bs,0) = block_operation_rowmajor(mappedvals);
else
mappedvals.template block<bs,bs>(0,i*bs) = block_operation_colmajor(mappedvals);
}
调用函数首先计算出 Mattype(从 2 个选项中(,然后使用正确的模板参数调用上述函数。
因此,我所有的算法都需要编写两次,并且我的代码穿插在这些布局检查中。有没有办法以与布局无关的方式做到这一点?请记住,此代码需要尽可能快。
理想情况下,我只会Map
一次数据,并将其用于所需的所有操作。但是,我能想到的唯一解决方案是在我需要访问块时为每个小块调用一次 Map 构造函数。
template<int bs, StorageOptions layout>
inline Map<Matrix<double,bs,bs,layout>> extractBlock(double *const vals,
const int bindex)
{
return Map<Matrix<double,bs,bs,layout>>(vals+bindex*bs*bs);
}
这个函数是否会被优化为零(通过像 GCC 7.3 或 Intel 2017 这样的现代编译器在-std=c++14 -O3
下(,还是每次调用这个函数时我都会支付一小笔罚款(每个块一次,并且有很多小块(?有没有更好的方法可以做到这一点?
你的extractBlock
很好,一个更简单但有点丑陋的解决方案是在block_operation
开始时使用重新解释转换:
using BlockType = Matrix<double,bs,bs,layout|DontAlign>;
BlockType* blocks = reinterpret_cast<BlockType*>(vals);
for(int i...)
block[i] = ...;
这仅适用于固定大小的矩阵。还要注意DontAlign
这很重要,除非您可以保证vals
在 16 甚至 32 字节上对齐,具体取决于 AVX 和bs
的存在......所以只需使用DontAlign
!
相关文章:
- EASTL矢量<向量<int>>连续的
- 向量的内存位置不连续
- 结构化绑定,无需复制即可获取子向量的连续元素
- 处理特征中两种存储布局的固定大小矩阵的连续向量
- 在向量中找到连续数字的更有效方法
- AVX2 根据条件将连续元素扩展到稀疏向量?(如AVX512 VP扩展)
- 为什么连续的向量:: push_back将导致不同数量的构造函数调用
- 在C 中添加连续的向量元素组的最快方法
- 如何在c++中增加向量中k个连续元素的值
- Boost.SSpirit.x3避免将同一类型的两个连续属性塌陷为向量
- 保持类的向量成员与类实例连续
- C++ 向量不分配连续内存
- 是在连续空间中分配的嵌套向量
- 为什么使用 push_back() 赋值时向量元素的地址不连续
- 是否有一个 c++ 矩阵库,我可以在其中索引具有非连续向量的矩阵,如 R 中的矩阵
- 是一个完全连续内存的向量数组
- 向量中连续数的计数
- 计算一个向量中不重复的连续元素的最大数目.c++
- 将R转换为Rcpp:向量中连续日期之间的平均时差
- C++向量总是连续的吗