C3015:OpenMP 'for' 语句中的初始化格式不正确
Posted
技术标签:
【中文标题】C3015:OpenMP \'for\' 语句中的初始化格式不正确【英文标题】:C3015: initialization in OpenMP 'for' statement has improper formC3015:OpenMP 'for' 语句中的初始化格式不正确 【发布时间】:2016-08-14 10:07:28 【问题描述】:我有并行扫描算法:Hillis & Steele (1986),我想并行执行内部 for 循环。
Error C3015 initialization in OpenMP 'for' statement has improper form OpenMP c:\users\matja\documents\visual studio 2015\projects\psseminar\openmp\main.c
我以前从未遇到过这个错误,我用谷歌搜索过,但没有发现任何有用的东西。
包括:
#include <omp.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <limits.h>
#include <windows.h>
代码块:
// ...
for (long long m = 0; m < M; m++)
long long offset = (long long)pow(2, m);
#pragma omp parallel for firstprivate(N, m, offset)
for (long long n = offset; n < N; n++)
long long ai = n - offset;
long long bi = n;
// ...
// ...
【问题讨论】:
【参考方案1】:根据 MSDN,当 OpenMP 未完全明确时,会引发 OP 发布的错误。这可能是因为编译器没有完全理解语句使用的 C99 语言
for (long long n = offset; n < N; n++)
尽管我没有 Visual C++ 编译器,但我发现 gcc 4.8.5 和 icc 16.0.3 无法编译它,需要使用适当的 C99 语言变体(即-std=c99
)编译代码。在谷歌搜索了一下之后,我没有找到适合 MSVC 的标志(事实上,***声称支持 ins MSVC 2013 是有限的(参见https://en.wikipedia.org/wiki/C99))。因此,您可以尝试的一种替代方法是将代码转换为
long long m;
for (m = 0; m < M; m++)
long long offset = (long long)pow(2, m);
long long n;
#pragma omp parallel for firstprivate(N, m, offset)
for (n = offset; n < N; n++)
long long ai = n - offset;
long long bi = n;
// ...
另外,请注意,如果您不在并行循环中修改,您可能可以去掉 N
、m
和 offset
的 firstprivate
子句并将它们更改为 shared
。
顺便说一句,我不同意 tahini 的回答,他们声称 #pragma omp parallel for
仅限于 int
或 unsigned int
,因为以下代码在 gcc 4.8.5 和 icc 16.0.3 中都能完美运行。
#include <omp.h>
#include <stdio.h>
void main (void)
long long m;
#pragma omp parallel for schedule
for (m = 0; m < 16; m++)
printf ("thread = %d, m = %d\n", omp_get_thread_num(), m);
【讨论】:
【参考方案2】:omp parallel for 中的迭代变量被限制为 int 或 unsigned int。 long long 不是有效的迭代器类型。
见
https://computing.llnl.gov/tutorials/openMP/#ParallelRegion
【讨论】:
我希望 int64_t 在合适的平台上工作,但我认为这不是可移植的期望。即使它可以工作,但在没有硬件支持的平台上它可能会很慢。 您可能想比较并行的内循环或外循环是否更快。有些人还使用 SIMD,测试多种方法很常见。 这个答案不正确。只需检查来自OpenMP 4.0 examples 的示例编号 29。 MSVC 不支持超过 2.0 的 OpenMP,它在 C(这里限制为 C89)和 C++ 之间做出了区分。在 VS2017 中似乎有更多的 C89 支持,但这个痛苦的问题仍然存在。 VS2019 也有同样的问题。必须使用 C89 变量声明,即使是 int。以上是关于C3015:OpenMP 'for' 语句中的初始化格式不正确的主要内容,如果未能解决你的问题,请参考以下文章