C3015:OpenMP“for”语句中的初始化格式不正确

Mat*_*Mav 4 c c++ openmp visual-studio visual-c++

我有并行扫描算法: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
Run Code Online (Sandbox Code Playgroud)

我以前从未遇到过这个错误,我用谷歌搜索过但没有发现任何有用的东西。

包括:

#include <omp.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <limits.h>
#include <windows.h>
Run Code Online (Sandbox Code Playgroud)

代码块:

// ...
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;
        // ...
    }
}
// ...
Run Code Online (Sandbox Code Playgroud)

Har*_*ald 6

根据 MSDN,OP 发布的错误是在 OpenMP 未完全明确时引发的。发生这种情况可能是因为编译器不完全理解该语句所使用的C99语言

for (long long n = offset; n < N; n++)
Run Code Online (Sandbox Code Playgroud)

尽管我没有 Visual C++ 编译器,但我发现 gcc 4.8.5 和 icc 16.0.3 无法编译它,需要使用适当的 C99 语言变体(即-std=c99)来编译代码。经过一番谷歌搜索后,我没有找到 MSVC 的正确标志(事实上,维基百科声称对 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;
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,请注意,您可能可以去掉firstprivatefor 和 子句Nm并将offset它们更改为sharedif 您不在并行循环中进行修改。

顺便说一句,我不同意 tahini 的答案,他们声称这#pragma omp parallel for仅限于intunsigned 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);
    }
}
Run Code Online (Sandbox Code Playgroud)