private 变量的值是处理 for 循环的某些迭代的每个处理器的私有值。换句话说,在 for 循环的一次迭代中赋给 private 变量的值不会传送给处理该 for 循环的其他迭代的其他处理器。而 shared 变量的当前值可处理 for 循环的迭代的所有处理器访问。处理循环迭代的一个处理器赋给 shared 变量的值可能会被处理循环的其他迭代的其他处理器识别。通过使用 #pragma MP taskloop 指令显式并行化并包含共享变量引用的循环,必须确保值的共享不会导致正确性问题(如竞争情况)。对显式并行化的循环中的共享变量的更新和访问,编译器不提供同步。
在分析显式并行化的循环时,编译器使用以下“缺省作用域规则”来确定变量是 private 变量还是 shared 变量:
如果变量未通过 pragma 显式分类,已声明为指针或数组,并且仅在循环内部使用数组语法进行引用,则该变量缺省分类为 shared 变量。否则,将被分类为 private 变量。
循环索引变量始终被视为 private 变量和返回存储变量。
强烈建议将显式并行化的 for 循环中使用的所有变量显式分类为 shared、private、reduction 或 readonly 变量,以避免使用“缺省作用域规则”。
由于编译器对共享变量的访问不执行同步,因此在对包含数组引用等的循环使用 MP taskloop pragma 之前必须格外谨慎。如果此类显式并行化的循环中存在迭代间数据依赖性,则其并行执行会导致错误结果。编译器不一定能够检测到此类潜在问题情况并发出警告消息。无论如何,编译器不会禁止具有潜在共享变量问题的循环的显式并行化。