c - 为 OpenMP 中的每个内部循环启动一个线程

标签 c arrays loops parallel-processing openmp

我是 OpenMP 的新手,我正在尝试启动一个单独的线程来处理二维数组中的每个项目。

本质上,这是:

for (i = 0; i < dimension; i++) {
    for (int j = 0; j < dimension; j++) {
        a[i][j] = b[i][j] + c[i][j];

我正在做的是:

#pragma omp parallel for shared(a,b,c) private(i,j) reduction(+:diff) schedule(dynamic)
    for (i = 0; i < dimension; i++) {
        for (int j = 0; j < dimension; j++) {
            a[i][j] = b[i][j] + c[i][j];

这实际上是否为每个 2D 项目启动了一个线程?我将如何测试它?如果错了,正确的做法是什么?谢谢!

注:代码已经大大简化

最佳答案

在您的代码示例中只有外部循环是并行的。您可以通过在内循环中打印 omp_get_thread_num() 进行测试,您会看到,对于给定的 i,线程数是相同的(当然,这个测试是说明性的而不是确定性的,因为不同的运行会给出不同的结果)。例如,与:

#include <stdio.h>
#include <omp.h>
#define dimension 4

int main() {
    #pragma omp parallel for
    for (int i = 0; i < dimension; i++)
        for (int j = 0; j < dimension; j++)
            printf("i=%d, j=%d, thread = %d\n", i, j, omp_get_thread_num());
    }

我得到:

i=1, j=0, thread = 1
i=3, j=0, thread = 3
i=2, j=0, thread = 2
i=0, j=0, thread = 0
i=1, j=1, thread = 1
i=3, j=1, thread = 3
i=2, j=1, thread = 2
i=0, j=1, thread = 0
i=1, j=2, thread = 1
i=3, j=2, thread = 3
i=2, j=2, thread = 2
i=0, j=2, thread = 0
i=1, j=3, thread = 1
i=3, j=3, thread = 3
i=2, j=3, thread = 2
i=0, j=3, thread = 0

至于你的其余代码,你可能想在一个新问题中添加更多细节(从小样本中很难分辨),但是例如,你不能将 private(j)j 仅在稍后声明时。在我上面的例子中它是自动私有(private)的。我想 diff 是我们在示例中看不到的变量。此外,循环变量 i 是自动私有(private)的(来自 version 2.5 spec - 在 3.0 规范中相同)

The loop iteration variable in the for-loop of a for or parallel for construct is private in that construct.

编辑:以上所有内容对于您和我所展示的代码都是正确的,但您可能对以下内容感兴趣。对于 OpenMP 版本 3.0(在例如 gcc version 4.4 中可用,但不是版本 4.3)有一个 collapse 子句,您可以在其中编写代码,但是 #pragma omp parallel for collapse (2) 并行化两个 for 循环(参见 the spec)。

编辑:好的,我下载了 gcc 4.5.0 并运行了上面的代码,但是使用 collapse (2) 得到了以下输出,现在显示了内部循环并行化:

i=0, j=0, thread = 0
i=0, j=2, thread = 1
i=1, j=0, thread = 2
i=2, j=0, thread = 4
i=0, j=1, thread = 0
i=1, j=2, thread = 3
i=3, j=0, thread = 6
i=2, j=2, thread = 5
i=3, j=2, thread = 7
i=0, j=3, thread = 1
i=1, j=1, thread = 2
i=2, j=1, thread = 4
i=1, j=3, thread = 3
i=3, j=1, thread = 6
i=2, j=3, thread = 5
i=3, j=3, thread = 7

评论 here如果您想并行化两个循环,(搜索“变通办法”)也与 2.5 版中的变通办法相关,但上面引用的 2.5 版规范非常明确(参见 A.35 部分中的不合格示例)。

关于c - 为 OpenMP 中的每个内部循环启动一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2215818/

相关文章:

c - 在 GtkTreeView 中启用中间字符串快速搜索

ios - 如何从我的数组中删除 "..."?

python - 高效计算和存储相似度矩阵

c++ - 在嵌套类中声明固定长度的数组

java - 绘制随机圆圈,将其坐标存储在数组中

javascript - 如何在 JavaScript 中将数组中的随机值分配给另一个数组中的项目(将名称数组分配给工作日数组)?

excel - VBA查找和替换不适用于所有列

c - 创建 newNode 时没有从 createNode(int) 函数返回创建的节点

从 YUV444 到 RGB888 的转换

c# - 在数组中,我们如何找到 2 个元素在给定数字中的差异..?少于 O(n^2) 时间