0

我正在使用 openMP编写最长公共子序列算法的并行版本。

顺序版本如下(并且可以正常工作):

// Preparing first row and first column with zeros
for(j=0; j < (len2+1); j++)
    score[0][j] = 0;

for(i=0; i < (len1+1); i++)
    score[i][0] = 0;

// Calculating scores
for(i=1; i < (len1+1); i++) {
    for(j=1; j < (len2+1) ;j++) {
        if (seq1[i-1] == seq2[j-1]) {
               score[i][j] = score[i-1][j-1] + 1;
        }
        else {
            score[i][j] = max(score[i-1][j], score[i][j-1]);
        }
    }
}

关键部分是填充分数矩阵,这是我试图主要并行化的部分。

一种方法(我选择)是:用反对角线填充矩阵,所以左上角和左上角的依赖总是得到满足。简而言之,我跟踪对角线(第三个循环,下面的变量i),线程并行填充该对角线。为此,我编写了以下代码:

void parallelCalculateLCS(int len1, int len2, char *seq1, char *seq2) {

int score[len1 + 1][len2 + 1];
int i, j, k, iam;
char *lcs = NULL;

for(i=0;i<len1+1;i++)
    for(j=0;j<len2+1;j++)
        score[i][j] = -1;

#pragma omp parallel default(shared) private(iam)
{
    iam = omp_get_thread_num();
// Preparing first row and first column with zeros
    #pragma omp for
    for(j=0; j < (len2+1); j++)
        score[0][j] = iam;

    #pragma omp for
    for(i=0; i < (len1+1); i++)
        score[i][0] = iam;

// Calculating scores
    for(i=1; i < (len1+1); i++) {
        k=i;
        #pragma omp for
        for(j=1; j <= i; j++) {
            if (seq1[k-1] == seq2[j-1]) {
                //  score[k][j] = score[k-1][j-1] + 1;
                score[k][j] = iam;
            }
            else {
            //  score[k][j] = max(score[k-1][j], score[k][j-1]);
                score[k][j] = iam;
            }
            #pragma omp atomic
            k--;
        }
    }

}
}

前两个循环(第一行和第一列)正常工作,线程以平衡的方式填充单元格。

当谈到填充矩阵(对角线)时,没有什么效果很好。我试图调试它,但似乎线程随机地行动和写东西。

我不知道出了什么问题,因为在前两个循环中根本没有问题。

任何想法?

PS我知道以对角线方式访问矩阵对缓存非常不友好,线程可能不平衡,但我现在只需要它工作。

PS #2 我不知道它是否有用,但我的 CPU 最多有 8 个线程。

4

2 回答 2

0

#pragma omp atomic意味着处理器将一次执行一个操作。您正在寻找#pragma omp for private(k):处理器将不再共享相同的值。再见,弗朗西斯

于 2014-01-10T20:03:16.443 回答
0

下面的嵌套for循环

 #pragma omp for
 for(j=1; j <= i; j++) 

将并行执行,每个线程具有不同的值,j没有特定的顺序。由于该omp for部分未指定任何内容,k默认情况下将在所有线程之间共享。因此,根据线程的顺序,k将在未知时间递减(即使使用omp atomic)。所以对于一个固定j的 , 的值k可能会在 for 循环体的执行过程中发生变化(在if子句之间,...)。

于 2014-01-10T20:00:33.357 回答