在与 OpenMP 并行的嵌套 for 循环中写入共享数组(通过指针)如何产生错误的结果
How can writing to a shared array (over a pointer) in a nested for loop parallelized with OpenMP produce wrong results?
我有一个非常奇怪的问题,我试图解决和理解。我有一个以下形式的嵌套 for 循环:
#pragma omp parallel for schedule(guided) shared(Array) collapse(3)
for (int i=istart; i<iend; i++)
{
for (int j=jstart; j<jend; j++)
{
for(int k=kstart; k<kend; k++)
{
Int IJK = (i*(jend-jstart) + (j-jstart))*(kend-kstart) + (k-kstart);
Array[3*IJK + 2] = an operation with some shared values;
}
}
}
这种形式有三个循环,分别是Array[3*IJK]
、Array[3*IJK + 1]
和Array[3*IJK+2]
。数组实际上也是一个共享指针,对于 IJK
的值,实际上调用了一个函数(内联)。
我首先尝试并行化所有循环,程序贯穿始终,但与我的串行结果相比,结果不同。
现在奇怪的部分来了。
具有相同结构但具有Array[3*IJK + 1]
的 for 循环在并行化时会产生正确的结果(在本例中其他循环是串行的)。但是一旦我并行化其他循环之一,我就会得到不同的结果。只有这个单一的循环在自身并行化时才能产生正确的结果。
另外,如果我不使用collapse
或collapse(2)
而不是collapse(3)
,我会得到不同的结果。只有使用上述#pragma
语句,我才能在Array[3*IJK + 1]
循环中获得正确的结果。
我认为这可能与Array
的写入顺序有关,但是对于有序子句和构造,我仍然得到错误的结果。
这是什么原因造成的?
你确定你的连环案例是正确的吗?
你的IJK
计算对我来说毫无意义;首先,它根本不取决于j
。 事实上,如果两个线程获得具有不同 j 的相同 (i,k) 对 - 当然可能使用 collapse(3)
- 将存在竞争条件,因为它们都将尝试写入相同的 IJK。
确定你不想要这样的东西吗
Int IJK = (i*(jend-jstart) + (j-jstart))*(kend-kstart) + (k-kstart);
?
相关文章:
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 取消引用指向整数的指针时获得不同的结果
- 指针数组中的意外结果
- 使用指针访问数组元素时出现意外结果
- C++数组和指针的大小的结果
- C++ 函数指针的计算结果为 1
- 对象指针打印结果以相反的顺序进行
- 使用 OpenCV 原始指针和 lambda 作为直方图的不同结果
- 插入指针数组会删除上一个结果
- 打印整数指针元素时的结果不同
- 错误:通过指针显示重复的结果
- 当应该删除其目标时,为什么此智能指针给出正确的结果
- 为什么我得到这个字符指针的不同结果?
- 在我的C++链表实现中取消引用节点指针,给出意想不到的结果
- 我可以将C 17 Capture lambda ConstexPR转换操作符的结果用作函数指针模板非类型参数吗?
- Cout删除了(未签名的字符)指针,给了我意外的结果
- 为什么无法将 std::bind 的结果分配给函数指针
- 如何否定MEM_FN创建的功能指针的结果
- 返回指向操作+的结果的指针
- 为什么在同一类中使用不同的(共享_ptr和正常)指针构造函数,我会得到不同的结果