使用 openmp 并行块中的预编译语句避免未使用的变量警告
Avoiding unused variable warnings with pre-compiler statements inside openmp parallel blocks
背景
我的问题是由一些特定问题的组合引起的。
- 我正在使用预处理器语句来确定要在生成的可执行文件中包含哪种计算
- 我正在对
default(none)
的块使用 openmp parallel(因为我很偏执)。
- 代码可以正确编译和运行,但可能会根据预处理器标志发出未使用的变量警告。从技术上讲,这不是错误,但我想删除这些警告(不,我不只是意味着禁用编译器警告,而是实际上消除了原因,即未使用的变量)。
基本上,我有一些形式
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_stuff;
#if FLAG_1
compute_more_stuff;
#endif
}
}
主要问题
为清楚起见,假设仅当 FLAG_1
为 true
时才需要变量 x
。我可以将 x
的声明及其用法包装在 #if FLAG1 ... #endif
语句中,但我仍然需要在 #pragma omp parallel
的变量列表中列出 x
,并且,至于我知道,我不能在 #pragma omp parallel
语句中嵌套 #if FLAG1 ... #endif
(它有几行长 - 有很多变量)。因此,我要么收到有关 pragma omp 中列出的不存在变量的错误,要么收到有关未使用变量的警告。
可能的(但不令人满意的)解决方案
在这种情况下,删除的变量都是 omp-private,我预先承认只需将 default(none)
替换为 default(private)
即可解决问题。也就是说,我确实喜欢 default(none)
的编码实践,并希望尽可能保留它。
另一种选择是简单地将 omp-parallel 分解成如下所示,但是 compute_stuff
和 compute_more_stuff
有一些共享的计算/内存访问,我'我喜欢避免重复。
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_stuff;
}
}
#if FLAG_1
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_more_stuff;
}
}
#endif
任何关于如何在保持代码可读性和高效性的同时保持良好编码习惯的想法都将不胜感激!
如果您使用的是 C++17,[[maybe_unused]]
属性是什么?:
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
[[maybe_unused]] variable_potencially_not_used;
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_stuff;
#if FLAG_1
variable_potencially_not_used = 1;
#endif
}
}
如果没有,替代方案是实现类似于 Q_UNUSED
宏的东西。你可以声明你自己的:
#define MAYBE_UNUSED(X) (void)X
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
MAYBE_UNUSED(variable_potencially_not_used);
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_stuff;
#if FLAG_1
variable_potencially_not_used = 1;
#endif
}
}```
背景
我的问题是由一些特定问题的组合引起的。
- 我正在使用预处理器语句来确定要在生成的可执行文件中包含哪种计算
- 我正在对
default(none)
的块使用 openmp parallel(因为我很偏执)。 - 代码可以正确编译和运行,但可能会根据预处理器标志发出未使用的变量警告。从技术上讲,这不是错误,但我想删除这些警告(不,我不只是意味着禁用编译器警告,而是实际上消除了原因,即未使用的变量)。
基本上,我有一些形式
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_stuff;
#if FLAG_1
compute_more_stuff;
#endif
}
}
主要问题
为清楚起见,假设仅当 FLAG_1
为 true
时才需要变量 x
。我可以将 x
的声明及其用法包装在 #if FLAG1 ... #endif
语句中,但我仍然需要在 #pragma omp parallel
的变量列表中列出 x
,并且,至于我知道,我不能在 #pragma omp parallel
语句中嵌套 #if FLAG1 ... #endif
(它有几行长 - 有很多变量)。因此,我要么收到有关 pragma omp 中列出的不存在变量的错误,要么收到有关未使用变量的警告。
可能的(但不令人满意的)解决方案
在这种情况下,删除的变量都是 omp-private,我预先承认只需将
default(none)
替换为default(private)
即可解决问题。也就是说,我确实喜欢default(none)
的编码实践,并希望尽可能保留它。另一种选择是简单地将 omp-parallel 分解成如下所示,但是
compute_stuff
和compute_more_stuff
有一些共享的计算/内存访问,我'我喜欢避免重复。
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_stuff;
}
}
#if FLAG_1
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_more_stuff;
}
}
#endif
任何关于如何在保持代码可读性和高效性的同时保持良好编码习惯的想法都将不胜感激!
如果您使用的是 C++17,[[maybe_unused]]
属性是什么?:
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
[[maybe_unused]] variable_potencially_not_used;
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_stuff;
#if FLAG_1
variable_potencially_not_used = 1;
#endif
}
}
如果没有,替代方案是实现类似于 Q_UNUSED
宏的东西。你可以声明你自己的:
#define MAYBE_UNUSED(X) (void)X
#pragma omp parallel \
default(none) \
shared(...) \
private(...)
MAYBE_UNUSED(variable_potencially_not_used);
{
#pragma omp for
for (i = 0; i < num_i; ++i) {
compute_stuff;
#if FLAG_1
variable_potencially_not_used = 1;
#endif
}
}```