在向量中搜索最大值和索引

时间:2021-03-18 19:03:31

标签: c multithreading performance parallel-processing openmp

我正在尝试并行化这段在列上搜索最大值的代码。 问题是并行版本运行速度比串行慢

可能由于最大值和索引的同步,对枢轴(列上的最大值)的搜索速度较慢,对吗?

int i,j,t,k;
    // Decrease the dimension of a factor 1 and iterate each time
for (i=0, j=0; i < rwA, j < cwA; i++, j++) {
    int i_max = i; // max index set as i
    double matrixA_maxCw_value = fabs(matrixA[i_max][j]);
    #pragma omp parallel for reduction(max:matrixA_maxCw_value,i_max) //OVERHEAD
    for (t = i+1; t < rwA; t++) {
        if (fabs(matrixA[t][j]) > matrixA_maxCw_value) {
            matrixA_maxCw_value = matrixA[t][j];
            i_max = t;
        }
    }
    if (matrixA[i_max][j] == 0) {
        j++; //Check if there is a pivot in the column, if not pass to the next column
    }
    else {
        //Swap the rows, of A, L and P
        #pragma omp parallel for //OVERHEAD
        for (k = 0; k < cwA; k++) {
            swapRows(matrixA, i, k, i_max);
            swapRows(P, i, k, i_max);
            if(k < i) {
                swapRows(L, i, k, i_max);
            }
        }
        lupFactorization(matrixA,L,i,j,rwA);
    }
}

void swapRows(double **matrixA, int i, int j, int i_max) {
    double temp_val = matrixA[i][j];
    matrixA[i][j] = matrixA[i_max][j];
    matrixA[i_max][j] = temp_val;   
}

我不想要不同的代码,但我只想知道为什么会发生这种情况,在维度为 1000x1000 的矩阵上,串行版本需要 4.1s,并行版本需要 4.28s

同样的事情(开销很小但有)发生在理论上可以毫无问题地并行完成的行交换上,为什么会发生?

1 个答案:

答案 0 :(得分:1)

你的并行化至少有两个问题

#pragma omp parallel for reduction(max:matrixA_maxCw_value,i_max) //OVERHEAD
for (t = i+1; t < rwA; t++) {
    if (fabs(matrixA[t][j]) > matrixA_maxCw_value) {
        matrixA_maxCw_value = matrixA[t][j];
        i_max = t;
    }
}

您正在获得所有这些中最大的索引,但这并不意味着它属于最大值。例如查看以下数组:

[8, 7, 6, 5, 4 ,3, 2 , 1]

如果你用两个线程并行,第一个线程会有 max=8 和 index=0,第二个线程会有 max=4 和 index=4。减少完成后,最大值将为 8,但索引将为 4,这显然是错误的。

OpenMP 具有考虑单个目标值的内置归约函数,但是在您的情况下,您希望将 max 和数组索引这两个值考虑在内进行归约。在 OpenMP 4.0 之后,可以创建自己的归约函数( User-Defined Reduction)。

您可以查看实现此类逻辑的完整示例 here

另一个问题是这部分:

   #pragma omp parallel for //OVERHEAD
    for (k = 0; k < cwA; k++) {
        swapRows(matrixA, i, k, i_max);
        swapRows(P, i, k, i_max);
        if(k < i) {
            swapRows(L, i, k, i_max);
        }
    }

您正在并行交换这些元素,这会导致状态不一致。

首先,您需要先解决这些问题,然后再分析为什么您的代码没有加速。

先正确再效率。但是除了当前实现的很多加速之外,并行执行的计算量足以证明并行的开销是合理的。

相关问题