c++ - 正确使用内部函数和openmp

标签 c++ loops openmp

我有一个调用内部函数的 for 循环:

some variables
for(int i=0; i< 10000000; i++)
    func(variables)

基本上,func 获取对某个数组 A 的引用,并在 A[i] 中插入值 - 所以我确信 每次调用 func 实际上都试图将一个值插入到 A 中的不同位置,并且所有其他输入变量保持与 for 循环之前相同。所以 func 是线程安全的。

我可以安全地将代码更改为

some variables
#pragma omp parallel for
for(int i=0; i< 10000000; i++)
    func(variables)

根据我从 openmp 教程中了解到的情况,这还不够好——因为 openmp 库不知道提供给 func 的变量实际上是线程安全的,因此这会产生执行同步的尝试,这会放慢速度,我需要将变量声明为私有(private)等。但实际上,在尝试上面的代码时,它似乎确实工作得更快且并行 - 这是预期的吗?我只是想确保我没有遗漏任何东西。

函数的声明:

 func(int i, int client_num, const vector<int>& vec)

最佳答案

首先,OpenMP 无法神奇地确定对您代码的依赖性。您有责任确保代码对于并行化是正确的。

为了安全地并行化 for 循环,func不得有循环携带流依赖,或迭代间依赖,尤其是对于先写后读模式。此外,您必须检查没有静态变量。 (实际上,在这个简短的回答中写下安全并行化的条件要复杂得多。)


您对 func 的描述说func会将一个变量写入一个不同的地方。如果是这样,您可以通过放置 pragma omp parallel for 来安全地并行化,除非其他计算不依赖于禁止并行化。

您的 func 原型(prototype): func(int i, int client_num, const vector<int>& vec)

有一个vector , 但它是一个常数,所以 vec不应该有任何依赖。从不同线程同时读取是安全的。

但是,你说输出不一样。这意味着出了点问题。不可能说出问题是什么。显示函数的原型(prototype)无济于事;我们需要知道完成了什么样的计算func .

尽管如此,诊断的一些步骤是:

  • 检查代码中的依赖关系。您不得具有以下所示的依赖关系。请注意数组 A具有循环携带的依赖性,这将阻止并行化:

for (int k = 1; k <N; ++k) A[k] = A[k-1]+1;

  • 检查func是可重入的或线程安全的。大多数情况下,静态和全局变量可能会终止您的代码。如果是这样,您可以通过私有(private)化 来解决这个问题。在 OpenMP 中,您可以在 private 中声明这些变量条款。此外,还有 threadprivate OpenMP 中的编译指示。

关于c++ - 正确使用内部函数和openmp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7982750/

相关文章:

C++ OpenMP 任务 - 通过引用传递问题

c++ - 不同线程数 openMP 上的相同程序执行时间

c++ - 声明 Reduction over Vector,在 1 个线程上运行会给出与没有 openmp 时不同的结果

c++ - boost::unordered_map::find 根据编译器优化级别产生不同的结果,而 boost::unordered_map::insert 产生相同的结果

c++ - 请建议一些比 C++ 中的 gotoxy 函数更好的东西

c# - 使用 C# 和 tableadapter 循环结果

bash - 为什么 'for' 循环比从文件读取的 'while' 循环更快?

c++ - AES_cbc_encrypt 是否添加填充?

c++ - 关于 C++ 中临时对象的确切销毁时间的问题

java - 循环逻辑错误