并行化文件名相似性比较

时间:2015-11-19 02:14:33

标签: c++ openmp similarity

http://matpalm.com/resemblance/jaccard_coeff/中提供的C ++代码开始,我正在努力快速比较文件名相似性。到目前为止,我设法得到"相似性"使用g ++和-fopenmp开关在我的Windows 7(x64)上编译好的代码。下面显示了代码的基本部分:

#pragma omp parallel num_threads(2)
{

    ofstream file(output_filename_for_thread().c_str());
    int window_finish = number_lines;

    #pragma omp for schedule(dynamic, 1000)
    for(int i=0;i<number_lines;i++) {

        int window_start = i+1;

        // compare each pair output high resemblances
        for (int j=window_start; j<window_finish; j++) {
            if (lines[i][5] == lines[j][5]){ 
            float resemblance = shingles_array[i]->resemblance_to(*shingles_array[j]);
            if (resemblance >= min_resemblance - 0.0001)
                file << lines[i] << "\n"
                     << lines[j] << "\n";
           }
        }
    }

    file.close();
}

与原始代码相比,此代码中最大的变化是输出类似的文件名而不是索引和分数。另外,我只打算比较以相同字母开头的文件名。所以这里是问题定义。当我仅指定2个线程时,此代码工作正常,但是当我将线程数增加到3个或更多(最多8个)时,程序执行会以某种方式提前完成而不会获得任何输出。什么是进一步调试此问题或更好地解决它的方法?如果我能让这些代码适用于任意数量的线程,那将是很棒的。我的初步测试表明,与Python版本相比,这个C ++代码快10倍,而在Python中的8个进程上运行时,单个线程至少快2倍。任何指导和评论将不胜感激。

2 个答案:

答案 0 :(得分:0)

您有多个帖子同时写入file。这最多导致数据竞争和未定义的行为。您需要同步对file的访问权限或将结果存储在线程本地容器中,组合它们,并在循环完成时生成输出。

答案 1 :(得分:0)

最简单的解决方案是将文件写入操作放在OpenMP临界区中,如下所示:

    // compare each pair output high resemblances
    for (int j=window_start; j<window_finish; j++) {
        if (lines[i][5] == lines[j][5]){ 
        float resemblance = shingles_array[i]->resemblance_to(*shingles_array[j]);
        if (resemblance >= min_resemblance - 0.0001) {
            #pragma omp critical
            {
            file << lines[i] << "\n"
                 << lines[j] << "\n";
            }
          }
       }
    }

请注意,这将在线程之间引入大量同步,性能将受到影响。