为特征中的两个存储布局处理固定大小矩阵的连续向量

时间:2018-05-06 03:09:20

标签: c++ eigen eigen3

外部库为我提供了一个Select ipno, SUM(IF(retcode<100,1,0)) As '<100', SUM(IF(retcode>=100 and retcode<200,1,0)) As '100s', SUM(IF(retcode>=200 and retcode<300,1,0)) As '200s', SUM(IF(retcode>=300 and retcode<400,1,0)) As '300s', SUM(IF(retcode>=400,1,0)) As '400s' From WebLog Group By ipno; s的原始指针,我希望将其映射到Eigen类型。原始数组在逻辑上是一个大型有序固定大小矩阵的有序集合,大小相同。主要问题是小密集矩阵可能是行主要或列主要排序,我想同时容纳它们。

我目前的做法如下。请注意,一个小的固定大小的块(在块数组中)的所有条目都需要在内存中连续。

double

调用函数首先计算Mattype(2个选项中的一个),然后用正确的模板参数调用上面的函数。

因此我的所有算法都需要写两次,我的代码中插入了这些布局检查。有没有办法以布局无关的方式做到这一点?请记住,此代码需要尽可能快。

理想情况下,我只需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); } 一次数据,并将其用于所需的所有操作。但是,我能想到的唯一解决方案是每当我需要访问块时,为每个小块调用一次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),或者每次调用此函数时我都会支付一小笔罚款(每个块一次,并且有很多小块)?有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

你的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的存在....所以只需使用{ {1}}!