如何通过矩阵的上三角形展平环?

时间:2016-10-09 14:31:31

标签: c++ loops openmp

我有一种情况,我使用openMP作为Xeon Phi协处理器,我有机会并行化“令人尴尬的并行”双循环。

然而,for循环遍历上三角形(包括对角线):

for (int i = 0; i < n; i++)
     // access some arrays with the value of i
     for (int j = i; j < n; j++)
         // do some stuff with the values of j and i

所以,我已经得到了循环的总大小,

for (int q = 0; q < ((n*n - n)/2)+n; q++)
    // Do stuff

但我在努力的地方是:

如何 q 计算 i j ?可能吗?

与此同时,我只是在做完整的矩阵,从那里计算i和j,只在j> = i时才做我的东西...但是这仍然留下了大量的线程开销。

3 个答案:

答案 0 :(得分:1)

如果我重述您的问题,要从i查找jq,您需要最大的i

    q >= i*n - (i-1)*i/2

j定义为

    j = i + (q - i*n - (i-1)*i/2)

如果你有这么大的i,那么

    (i+1)*n - i*(i+1)/2 > q                             >= i*n - (i-1)*i/2
     n-i                > (q - i*n - (i-1)*i/2)         >= 0
     n                  > j = i + (q - i*n - (i-1)*i/2) >= i

这是找到i的第一个迭代方法:

    for (i = 0; q >= i*n - (i-1)*i/2; ++i);
    i = i-1;

如果迭代qi的计算很可能会利用迭代过程。

第二种方法可以使用sqrt,因为

    i*n - i²/2 + i/2 ~ q
    i²/2 - i(n+1/2) + q ~ 0
    delta = (n+0.5)² - 2q
    i ~ (n+0.5) - sqrt(delta)

i可以定义为floor((n+0.5) - sqrt((n+0.5)² - 2q))

答案 1 :(得分:0)

好的,就我所知,这不是一个答案。但是,这是一种解决方法(目前)。

我正在考虑它,创建一个数组(或相应的指针),a[(n*n + n)/2 + n][2],并在我的调用代码中读取相应的ij值,然后传递给它我的功能将允许加速。

答案 2 :(得分:0)

你可以让你的循环迭代,因为它在整个矩阵上迭代 只是为了跟踪当前行,每次输入新行时,都会使用该行的值增加索引。

然后:i == linej == i%n

请参阅此代码:

int main() {

    int n = 10;
    int line = 0;
    for (int i=0; i<n*n; i++){
        if (i%n == 0 && i!=0){
            line++;
            i += line;
            cout << endl;
        }
        cout << "("<<line<<","<<i%n<<")";
    }
    return 0;
}

Running Example