2017-08-13 86 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