两个omp for循环之间的区别

时间:2013-04-15 22:31:56

标签: c++ parallel-processing openmp

我刚刚开始使用OpenMP并且正在编写一个函数,它将数组划分为numBlocks块并通过检查{{1来计算每个块上的直方图(即每个块一个直方图)每个块的元素(在代码I' m提供中,直方图通过整数blockSize1记录块中元素的可分性。

在第一个numBuckets循环中,我使用以下命令为每个块创建一个线程:

omp for

以另一种方式实现它,我请求每个线程对#pragma omp for schedule(static) for(uint blockNum = 0; blockNum < numBlocks; blockNum++){ for(uint blockSubIdx = 0; blockSubIdx < blockSize; blockSubIdx++){ uint idx = blockNum * blockSize + blockSubIdx; // Compute histogram here by examining array[idx] } } 个元素进行操作,我之前断言blockSize

array.size() == numBlocks * blockSize

如果我增加线程数(使用#pragma omp for schedule(static, blockSize) for(uint idx = 0; idx < array.size(); idx++){ uint blockNum = idx / blockSize; // Compute histogram here by examining array[idx] } )高于某个阈值(我的计算节点上为78),则第二种方法无法正常工作 - 结果直方图值与串行计算值不匹配。

根据https://computing.llnl.gov/tutorials/openMP/,看起来第二种方法中的大小export OMP_NUM_THREADS的块是连续的,所以我不清楚它为什么会失败。但是,似乎多个线程正在写入直方图中的相同索引。我有什么微妙之处吗?

以下是整个源代码的要点:https://gist.github.com/anonymous/5391777

更新:线程阈值确实显示对blockSize的某些依赖性。它不是我试图理解的阈值的特定值,而是阈值的存在。

1 个答案:

答案 0 :(得分:2)

在我看来,你正试图融合循环。你可以试试这个。我不知道这是否能回答你的问题。

#pragma omp parallel for schedule(static)
for(uint n = 0; n < (numBlocks*blockSize); n++){
    uint blockNum = n/blockSize;
    uint blockSubIdx = n%blockSize;
    uint idx = blockNum * blockSize + blockSubIdx;
    // Compute histogram here by examining array[idx]
}

另外,为什么要尝试增加线程数?您的CPU一次只能运行一定数量的硬件线程。增加OpenMP的线程数我认为不会有助于提高性能。为什么不将它们保留为默认值?

最后,如果根据idx计算直方图需要不同的时间,您可能需要尝试使用schedule(dynamic)