用于在一维数组上嵌套循环操作的正确 openmp 指令
Proper openmp directives for nested for loop operating on 1D array
我需要迭代一个数组,并根据需要一些迭代本身的计算来分配每个元素。删除所有不必要的细节,程序归结为这样的东西。
float output[n];
const float input[n] = ...;
for (int i = 0; i < n; ++i) {
output[i] = 0.0f;
for (int j = 0; j < n; ++j) {
output[i] += some_calculation(i, input[j]);
}
}
some_calculation
不会更改其参数,也不会具有内部状态,因此其线程是安全的。查看循环,我知道外部循环是线程安全的,因为不同的迭代输出到不同的内存位置(不同的output[i]
(,并且在循环运行时永远不会更改input
的共享元素,但内部循环不是线程安全的,因为它在output[i]
上具有竞争条件,因为它在所有迭代中都会更改。
因此,我想生成线程并让它们为不同的i
值工作,但input
的整个迭代应该是每个线程的本地,以免在output[i]
上引入竞争条件。我认为以下内容可以实现这一点。
std::array<float, n> output;
const std::array<float, n> input[n];
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
output[i] = 0.0f;
for (int j = 0; j < n; ++j) {
output[i] += some_calculation(i, input[j]);
}
}
我不确定这是如何处理内部循环的。在不同i
上工作的线程应该能够并行运行循环,但我不明白我是否允许它们在没有另一个#pragma omp
指令的情况下运行。另一方面,我不想意外地允许线程在同一i
上以不同的j
值运行,因为这会引入竞争条件。我也不确定我是否需要一些关于如何处理这两个数组的额外规范。
最后,如果此代码位于将要重复调用的函数中,它是否需要parallel
指令,或者是否可以在我的主循环开始之前调用一次。
void iterative_step(const std::array<float, n> &input, const std::array<float, n> &output) {
// Threads have already been spawned
#pragma omp for
for (int i = 0; i < n; ++i) {
output[i] = 0.0f;
for (int j = 0; j < n; ++j) {
output[i] += some_calculation(i, input[j]);
}
}
int main() {
...
// spawn threads once, but not for this loop
#pragma omp parallel
while (...) {
iterative_step(input, output);
}
...
}
我浏览了其他各种问题,但它们是关于不同竞争条件下的不同问题,我对如何概括答案感到困惑。
你不希望omp parallel
在main
。 您使用的omp for
将仅为以下for (int i
循环创建/重用线程。 对于任何特定的i
值,j
循环将完全在一个线程上运行。
另一件有帮助的事情是将output[i]
结果计算成局部变量,然后在完成j
循环后将其存储到output[i]
中。
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- OpenMP阵列性能较差
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- OpenMP 与有序和关键指令并行
- 用于在一维数组上嵌套循环操作的正确 openmp 指令
- OpenMP 手工还原指令
- 确定如何实现OpenMP原子指令
- 我如何知道在 OpenMP 中"为指令"完成了多少工作?
- 使用OpenMP分配数组的特殊指令
- 如何在 OpenMP 线程专用指令中使用对象的直接初始化
- OpenMP 原子和非原子读/写在x86_64上生成相同的指令
- OpenMP-主指令中的并行区域
- 在c++ STL类型的静态实例上使用OpenMP threadprivate指令
- 如何以一种很好的方式禁用OpenMP指令
- 用于并行for循环的c++ OpenMP指令
- 第一私有变量结构中允许的OpenMP调用和指令
- SIMD指令缺少OpenMP if子句
- OpenMP奇怪的行为与SIMD线性和并行的线性指令
- OpenMP对性能的影响:私有指令vs.在构造中声明变量
- OpenMP中单个指令和section指令的区别