c - e 在这里取什么值?
问题描述
我有以下代码(注意:这是为了帮助我理解这个概念,所以它是一个示例代码,而不是我打算运行的东西)
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
构造将执行限制为团队的任何一个线程(e
仍然在所有线程之间共享,请参阅https://www.openmp.org/spec-html/5.1/openmpsu113.html#x148-1600002.21.1)。
当被选中的线程遇到task
构造时,OpenMP 规范要求创建的任务从task
继承e
变量的共享属性(shared),因此所有创建的任务将看到相同的变量,并且被选中的线程可能会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
该副本将使用当前值初始化,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)。
推荐阅读
- python - 如何在 PyGame 中创建一个矩形作为精灵
- python - 如何获取 Android 上的窗口位置或键盘高度?
- android - 水平放置菜单项
- apache-spark - 如何使用 GCP 实例访问 Spark Web UI?
- android - Android Q 保存的媒体文件未显示在图库中
- c++ - 在 CentOS 8 中安装较旧的 gcc/g++ 版本
- jquery - jQuery 输入框自动添加 DOT 为 Currency 格式并且只允许数字
- react-native - 按钮在 MapView 标注 React Native 中不起作用
- c++ - 尝试计算 pi 时不断得到 0
- scala - lmcoursier.internal.shaded.coursier.error.FetchError$DownloadingArtifacts: Error fetching artifacts: 是什么意思?