2017-08-13 62 views
0

我想在OpenMP线程上按列平均分割一个Eigen动态大小的数组。本征:用于OpenMP的分割阵列

      thread 0 | thread 1 | thread 2 
[[0, 1, 2],    [[0], | [[1], | [[2], 
[3, 4, 5], becomes:  [3], | [4], | [5], 
[6, 7, 8]]     [6]] | [7]] | [8]] 

我可以使用block方法来做到这一点,但我不知道,如果将本征承认每个线程的子阵列占据的连续内存。

当我读块类型的documentation,具有与以下描述的InnerPanel模板参数:

InnerPanel为真,如果块映射到一组一排主要 矩阵或行的至列主矩阵的列(可选)。参数 允许在编译时确定在块表达式上对齐访问 是否可能。

Eigen是否知道每个OpenMP线程在子数组上的矢量化是可能的,因为每个子数组实际上都占用连续的内存?

如果没有,如何使Eigen知道这一点?

程序:

#include <Eigen/Eigen> 
#include <iostream> 
int main() { 
    // The dimensions of the matrix is not necessary 8 x 8. 
    // The dimension is only known at run time. 
    Eigen::MatrixXi x(8,8); 
    x.fill(0); 
    int n_parts = 3; 
    #pragma omp parallel for 
    for (int i = 0; i < n_parts; ++i) { 
     int st = i * x.cols()/n_parts; 
     int en = (i + 1) * x.cols()/n_parts; 
     x.block(0, st, x.rows(), en - st).fill(i); 
    } 
    std::cout << x << "\n"; 
} 

结果(g++ test.cpp -I<path to eigen includes> -fopenmp -lgomp):

0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
+0

SO必须睡觉。 –

回答

1

为了确保块的表达确实占用连续的存储,使用middleCols(或leftColsrightCols)代替:

#include <Eigen/Core> 
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> 
void inspectBlock(const Eigen::Block<XprType, BlockRows, BlockCols, InnerPanel>& block) 
{ 
    std::cout << __PRETTY_FUNCTION__ << '\n'; 
} 

int main() { 
    Eigen::MatrixXi x(8,8); 
    inspectBlock(x.block(0, 1, x.rows(), 2)); 
    inspectBlock(x.middleCols(1, 2)); 
} 

Res ULT:

void inspectBlock(const Eigen::Block<ArgType, BlockRows, BlockCols, InnerPanel>&) [with XprType = Eigen::Matrix<int, -1, -1>; int BlockRows = -1; int BlockCols = -1; bool InnerPanel = false] 
void inspectBlock(const Eigen::Block<ArgType, BlockRows, BlockCols, InnerPanel>&) [with XprType = Eigen::Matrix<int, -1, -1>; int BlockRows = -1; int BlockCols = -1; bool InnerPanel = true] 

注:-1Eigen::Dynamic的值,即不固定在编译时。

当然,如果你的矩阵是主要行,你可以拆分int topRows,middleRowsbottomRows,而不是。

+0

这是否也让Eigen知道子阵列的内存对齐? –

+0

嗯。 InnerPanel是真实的。让我测试一下,如果子阵列的维数/边界不是simd寄存器大小的倍数,会发生什么情况。 –

+0

我不知道Eigen可以被告知子块实际上是对齐的。 (我原以为'Ref'可以被告知只接受对齐的块,但我没有设法生成一个工作示例) - 如果您真的非常需要,可以使用“AlignedMap”进行手动构建。 – chtz