为什么人们在 OpenMP 循环之前声明迭代值
why do people declare iterated values before loop for openmp?
因此,据我所知,在所有版本的openmp中,以下任何一个都是正确的:
//int i declared in loop, explicitly private
#pragma omp parallel for
for (int i = 0; i < NUMEL; i++)
{
foo(i);
}
//int i declared outsize loop, but is the iterated value, implicitly private
int i;
#pragma omp parallel for
for (i = 0; i < NUMEL; i++)
{
foo(i);
}
但是,我更常看到第二个而不是第一个。为什么?
因为不是每个人都用C++编写或针对符合 C99 的 C 编译器。有些人更喜欢坚持旧的 C 要求,即在块的开头声明变量,以便代码与较旧的(C99 之前)C 编译器更兼容。
在
循环之外声明循环迭代器容易出错,通常没有必要。 也许SO上关于OpenMP的问题中,最大的部分是由于内部循环和在循环外声明迭代器引起的问题。
int i,j;
#pragma omp parallel for
for(i=0; i<n; i++) { //OpenMP makes the parallel index private by default
for( j=0; j<n; j++) { //error j should be private but is shared by default
如果使用循环初始声明,则不会发生此类错误
#pragma omp parallel for
for(int i=0; i<n; i++) { //i is private
for(int j=0; j<n; j++) {// j is private now
不幸的是,GCC 和 ICC 默认使用的 C 方言 GNU89 不允许循环初始声明(即使它确实允许混合声明),因此 C99(例如 GNU99)方言或C++对于循环初始声明是必需的。
但是,有时在需要最后一个迭代器时在循环外部声明迭代器很有用。 在这种情况下,应使用lastprivate
。 例如,如果我只想遍历四个元素的多个,然后知道要使用多少个最终元素,我可以这样做:
#include <stdio.h>
int main() {
int i,j;
int n,m;
n = 10;
m = 25;
#pragma omp parallel for lastprivate(i,j)
for(i=0; i<(n & -4); i++) {
for(j=0; j<(m & -4); j++) {
}
}
printf("%d %dn",i, j); //output 8, 24
}
一位程序员曾经告诉我,他更喜欢第二个版本,因为你可以在循环退出后在调试器中看到i
的值,这对于具有复杂条件或breaks
的循环很有用。 但是这些循环不能很好地并行化,所以如果这是 OpenMP 示例的原因,我会感到惊讶。
相关文章:
- 为什么此函数返回一个link_type但它被声明为迭代器
- 在 leveldb 的 c++ 示例中声明迭代器时出现分段错误
- 如何修复错误,迭代器未在此范围内声明,并且迭代器未命名类型'
- 如何将迭代器变量声明为私有成员变量
- 什么时候足以将const_iterator声明为const迭代器
- 使用std ::迭代特征和自动定义函数声明的函数
- 声明一个模板函数,该函数接收两个泛型迭代器作为参数
- C 迭代器从Typedef std :: Map作为模板参数声明
- 声明迭代功能的界面
- 在 GCC 上自动声明映射迭代器错误
- ISO C++禁止声明没有自动迭代器类型的“it”
- 声明泛型迭代器
- 如何在 C++ 中为堆栈集声明迭代器
- 如何向派生类对象声明迭代器
- 如何为未知容器声明迭代器变量
- 用vc++声明迭代器
- 模板错误:没有在作用域中声明迭代器
- 如何通过decltype声明迭代器的值
- 错误:为vector声明迭代器时模板实参1无效
- 为什么人们在 OpenMP 循环之前声明迭代值