| 跳过导航链接 | |
| 退出打印视图 | |
|
Oracle Solaris Studio 12.3:OpenMP API 用户指南 Oracle Solaris Studio 12.3 Information Library (简体中文) |
要启用作用域检查,请使用 -xvpara 和 -xopenmp 选项在优化级别 -xO3 或更高级别上编译 OpenMP 程序。如果只使用 -xopenmp=noopt 来编译程序,作用域检查将不起作用。如果优化级别低于 -xO3,编译器将发出警告消息,且不执行任何作用域检查。
在作用域检查期间,编译器将检查所有 OpenMP 构造。如果确定有些变量的作用域时引发问题,编译器会发出警告消息,有时还会建议使用正确的数据共享属性子句。
例如:
示例 7-1 作用域检查
% cat t.c
#include <omp.h>
#include <string.h>
int main()
{
int g[100], b, i;
memset(g, 0, sizeof(int)*100);
#pragma omp parallel for shared(b)
for (i = 0; i < 100; i++)
{
b += g[i];
}
return 0;
}
% cc -xopenmp -xO3 -xvpara source1.c
"source1.c", line 10: Warning: inappropriate scoping
variable 'b' may be scoped inappropriately as 'shared'
. write at line 13 and write at line 13 may cause data race
"source1.c", line 10: Warning: inappropriate scoping
variable 'b' may be scoped inappropriately as 'shared'
. write at line 13 and read at line 13 may cause data race
如果优化级别低于 -xO3,编译器将不进行作用域检查:
% cc -xopenmp=noopt -xvpara source1.c "source1.c", line 10: Warning: Scope checking under vpara compiler option is supported with optimization level -xO3 or higher. Compile with a higher optimization level to enable this feature
以下示例显示了潜在的作用域错误:
示例 7-2 作用域错误示例
% cat source2.c
#include <omp.h>
int main()
{
int g[100];
int r=0, a=1, b, i;
#pragma omp parallel for private(a) lastprivate(i) reduction(+:r)
for (i = 0; i < 100; i++)
{
g[i] = a;
b = b + g[i];
r = r * g[i];
}
a = b;
return 0;
}
% cc -xopenmp -xO3 -xvpara source2.c
"source2.c", line 8: Warning: inappropriate scoping
variable 'r' may be scoped inappropriately as 'reduction'
. reference at line 13 may not be a reduction of the specified type
"source2.c", line 8: Warning: inappropriate scoping
variable 'a' may be scoped inappropriately as 'private'
. read at line 11 may be undefined
. consider 'firstprivate'
"source2.c", line 8: Warning: inappropriate scoping
variable 'i' may be scoped inappropriately as 'lastprivate'
. value defined inside the parallel construct is not used outside
. consider 'private'
"source2.c", line 8: Warning: inappropriate scoping
variable 'b' may be scoped inappropriately as 'shared'
. write at line 12 and write at line 12 may cause data race
"source2.c", line 8: Warning: inappropriate scoping
variable 'b' may be scoped inappropriately as 'shared'
. write at line 12 and read at line 12 may cause data race
此虚构示例显示了作用域检查可以检测到的一些典型作用域错误。
r 被指定为归约变量,其操作为 +,但实际上操作应为 *。
a 的作用域显式确定为 PRIVATE。由于 PRIVATE 变量没有初始值,因此第 11 行中对 a 的引用可能会显示乱码。编译器会指出此问题,并建议程序员考虑将 a 的作用域确定为 FIRSTPRIVATE。
变量 i 是循环索引变量。有些情况下,如果在循环后使用循环索引值,程序员可能希望将其指定为 LASTPRIVATE。但在示例中,在循环后根本没有引用 i。编译器会发出警告,并建议程序员将 i 的作用域确定为 PRIVATE。使用 PRIVATE 而不是 LASTPRIVATE 可以提高性能。
程序员不为变量 b 显式指定数据共享属性。根据 OpenMP 3.0 规范第 79 页的第 27-28 行,将 b 的作用域隐式确定为 SHARED。但是,将 b 的作用域确定为 SHARED 将导致数据争用。b 的正确数据共享属性应为 REDUCTION。