繁体   English   中英

openMP的最长公共子序列

[英]Longest Common Subsequence with openMP

我正在使用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个线程。

以下嵌套for循环

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM