当变量是数组元素时,我可以使用OpenMP减少吗?

时间:2014-11-19 09:26:08

标签: c++ arrays openmp reduction

OpenMP手册说

  

declare reduction指令中的类型名称不能是函数类型,数组类型,引用类型或使用constvolatilerestrict限定的类型

如何将结果生成到数组元素中?我开始时:

int main()
{
    // create an input array
    static const int snum = 5000;
    int input[snum];
    for(int i=0; i<snum; ++i){
        input[i] = i+1;
    }

    // shared output variables for reduction
    int sum[2];
    sum[0] = 0;
    sum[1] = 0;

#pragma omp parallel for
#pragma omp declare reduction(+:sum[0])
#pragma omp declare reduction(+:sum[1])
    for(int i=0; i<snum; ++i) {
            int* p = input+i;
            if(i%2==0)
                sum[0] += *p;
            else
                sum[1] += *p;
        }
}

这会产生编译错误:

27013152.cpp:16:9: error: ‘#pragma’ is not allowed here
 #pragma omp declare reduction(+:sum[0])
         ^~~
27013152.cpp:17:33: error: ‘sum’ does not name a type
 #pragma omp declare reduction(+:sum[1])
                                 ^~~
27013152.cpp:17:36: error: expected ‘:’ before ‘[’ token
 #pragma omp declare reduction(+:sum[1])
                                    ^

2 个答案:

答案 0 :(得分:1)

您误解了您所得到的错误。这并不意味着你不能对交替元素进行减少。这意味着您无法将数据缩减为数组元素。

也就是说,你不能reduction(+:sum[0])。但是你可以将其缩减为另一个标量变量,然后复制到数组的元素中:

void sum_int(const int input[], int num, int *sum)
{
    int sum_even = 0, sum_odd = 0;

    #pragma omp parallel for reduction(+:sum_even) reduction(+:sum_odd)
    for (int i = 0; i < num; i++) {
            if (i % 2 == 0)
                    sum_even += input[i];
            else
                    sum_odd += input[i];
    }

    sum[0] = sum_even;
    sum[1] = sum_odd;
}

答案 1 :(得分:1)

自OpenMP 4.5以来,现在可以减少C / C ++中的数组。 基本上,您必须指定数组部分(参见OpenMP 4.5规范的第2.4节,第44页)。 您的#pragma规范如下所示:

#pragma omp parallel reduction(+:sum[:2])

要小心这一点,你必须意识到每个线程都会 分配自己的数组部分版本;如果你这么做的话 有许多线程的数组,你将使你的内存需求爆炸。