我可以使用openMP并行与一个面向对象的循环迭代器,我想保存?



我正在研究一个由细胞,相互作用的对象组成的模拟,并随着时间的推移而演变。我正在考虑使用OpenMP并行命令并行化我的代码,并希望我的单元格(对象)每个时间步并行更新,下面您可以看到部分代码。

#pragma omp parallel for default(none) shared(cells, maxCellReach, parameters, cellCellJunctions, timestepDistance) firstprivate(timestep), reduction(+ : centerOfMass)
for (auto it = cells.begin(); it != cells.end(); it++) {
maxCellReach = std::max(it->getNucleus()->getCellReach(), maxCellReach);
it->ApplyIntercellularForce(cellCellJunctions, Constants::junctionCreateDistance, parameters);
it->step(timestep, parameters);
centerOfMass += it->GetCenterOfMass();
}

我读到openMP并行for循环的循环迭代器变量总是私有的。然而,我希望所有的单元格一起更新。这段代码是否实现了这一点,或者我是否需要使用openMP的不同方法?

我在网上找了一下,但找不到任何关于让循环迭代器共享变量或类似for循环的东西。

为了能够在for循环中使用OpenMP,它必须满足"规范循环格式";按标准规定。例如,在OpenMP 4.5规范第2.6节(从第53页开始)和OpenMP 5.0规范第2.9.1节(从第95页开始)中描述了它。

两个标准都指定循环形式为

for (init-expr; test-expr; incr-expr) structured-block

init-exprtest-exprinc-expr有不同的限制。虽然4.5已经允许在c++中使用random-access-iterator-type,但它不允许在test-expr中使用!=。5.0标准修复了这个问题,在撰写本文时,最新版本的gcc和clang几乎完全实现了这个问题。为了与这些编译器的旧版本兼容,如果可能的话,您可能不得不使用<。有关哪个编译器的哪个版本实现了哪个标准的更多信息,请参阅此处。

如果你的迭代器是而不是允许随机访问,事情变得更加复杂。例如,请参阅此回答中的任务代码。

在第99页,5.0标准甚至允许c++ 11中基于范围的for循环,因此您可以编写更优雅的循环。

在OpenMP 5.2中,仍然至少有一个特殊情况(#pragma omp simd)操作非指针随机访问迭代器。

最新更新