使用openMP的Boyer moore字符串搜索

时间:2014-03-30 06:35:51

标签: c openmp

我正在使用OpenMP和C实现Boyer-Moore算法。我正在使用gcc编译器。我的串行代码工作正常,但在使用OpenMP进行并行化时,我使用了

#pragma omp parallel for

但我得到的输出不正确。我为不同的运行获取不同的关键字计数,并且关键字的偏移量也不正确。 这个#pragma omp parallel for指令有什么特殊规则吗?

这是for循环的代码:

#pragma omp parallel
{
    #pragma omp for
    for(k=0;k<=s.st_size;k+=chunksize-plen)
    {
        fseek(fp,k,SEEK_SET);
        fread(data, chunksize, sizeof(unsigned char), fp);
        data[chunksize]='\0';
        boyermoore(data,pattern,k,&c);
    }
} 

2 个答案:

答案 0 :(得分:1)

这些语句不能安全地并行化(是一个单词?):

    fseek(fp,k,SEEK_SET);
    fread(data, chunksize, sizeof(unsigned char), fp);

一个线程与另一个线程同时设置位置或者在另一个线程中读取之前,将会造成严重破坏。更不用说每个线程都会读入相同的data缓冲区。

答案 1 :(得分:0)

首先,您需要最小化并行区域内共享的数据量。对于这段代码,我认为你需要将data设为私有,如果它是一个内存缓冲区,请确保每个线程都是独立的:

#pragma omp parallel private(data)
{
    data = malloc( chunksize ); /* or whatever size it should be */
    #pragma omp for
    { /* ... */ }
    free(data);
}

或者,您可以在并行区域之前一次为所有线程分配缓冲区,并使用omp_get_thread_num找出应该使用缓冲区的哪个部分:

buffer = malloc ( chunksize * omp_get_max_threads() );
#pragma omp parallel private(data)
{
    data = (char*)buffer + omp_get_thread_num()*chunksize;
    /* ... */
}

也许patternc也应该是私密的;没有看到boyermoore函数的代码就很难说。

其次,您需要同步对任何共享变量的访问(除非这些变量仅用于读取)。特别是,任何具有文件的操作都应该是同步的,例如,在#pragma omp critical的帮助下:

#pragma omp critical
{
    fseek(fp,k,SEEK_SET);
    fread(data, chunksize, sizeof(unsigned char), fp);
}

第三,您需要确保boyermoore函数及其调用的任何函数都是线程安全的,并且可以在没有数据争用的情况下同时执行。通常,需要同步对共享状态(例如全局变量)的任何访问。此外,如果任何指针传递给函数(例如&c似乎是可疑的),您需要确保每个线程中的那些指向不同内存或者同步内存的修改。