c - e 在这里取什么值?

标签 c multithreading openmp

我有以下代码(注意:这是为了帮助我理解这个概念,所以它是一个示例代码,而不是我打算运行的东西)

List ml; //my_list
Element *e;
#pragma omp parallel
#pragma omp single
{
    for(e=ml->first;e;e=e->next)
    #pragma omp task 
    process(e);//random function
}
有人提到 e 将始终具有相同的值,我试图思考为什么会这样以及值将是什么。
我的尝试/推理:
e 的值在 pragma omp single 内部发生变化,这些更改不会在任务内部执行(如果我没记错的话,除非我使用类似 firstprivate(e) 的东西,否则单个区域的值不会被带到任务内部,此外,它将采用的值将是随机的,因为我们没有将 e 初始化为单个和并行 omp 区域之外的任何变量,并且 e 将作为一个值,例如,如果我们在外部初始化为值 x,那么 e 将始终为 x
任何帮助纠正或验证我的推理将不胜感激。

最佳答案

我在您的示例中添加了一些评论,希望能够使行为更加清晰。

List ml; //my_list
Element *e;

#pragma omp parallel  // e is shared for the parallel region
#pragma omp single
{
   for(e=ml->first;e;e=e->next)
     #pragma omp task  // since e is shared, all tasks will see the "same" e
     process(e);
}
会发生什么(由上面的评论指出):你声明 e超出 parallel 的范围结构体。根据 OpenMP 规范,该变量将在所有正在执行的线程之间共享。 single然后,constructs 将执行限制为团队的任何一个线程(e 仍然在所有线程之间共享,请参阅 https://www.openmp.org/spec-html/5.1/openmpsu113.html#x148-1600002.21.1 )。
当拾取线程遇到 task构造,OpenMP 规范要求创建的任务来自 task继承 e 的共享属性变量(共享),因此所有创建的任务将看到相同的变量,并且选择的线程可能会覆盖 e执行 for 时的变量环形。
这就是 firstprivate(e)进来:
List ml; //my_list
Element *e;

#pragma omp parallel  // e is shared for the parallel region
#pragma omp single
{
  for(e=ml->first;e;e=e->next)
  #pragma omp task firstprivate(e) // task now receives a private "copy" of e
    process(e);
}
在这里,创建任务将拥有 e 的私有(private)副本。用当前值 e 初始化随着挑选的线程通过for环形。
解决此问题的另一种方法是:
List ml; //my_list

#pragma omp parallel  
#pragma omp single
{
  Element *e;   // e is thread-private inside the parallel region
  for(e=ml->first;e;e=e->next)
  #pragma omp task // task now receives a private "copy" of e w/o firstprivate
    process(e);
}
因为在本例中,OpenMP 规范要求变量应被视为指定 firstprivate(e)。 (见 https://www.openmp.org/spec-html/5.1/openmpsu113.html#x148-1610002.21.1.1)。

关于c - e 在这里取什么值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66567171/

相关文章:

c - C 中的递归多线程

c - "return list == NULL ? 0 : list->value + fun(list->next)"是做什么的?

c# - 我可以限制我的 C# 应用程序的 I/O

multithreading - ARM STLR 内存排序语义

带参数的 C++ 简单线程(无 .net)

python - 多核机器上单精度和 double 组矩阵乘法的性能下降

char name[1],但是当我输入 13 个字符时,屏幕上会发生奇怪的事情

c - 哪种语言有助于为有效的 C 程序创建报告

c++ - 多线程 (openMP) - 有多少并行线程

c - 在顶层使用 OpenMP 分支递归函数