Max Reduction Open MP 2.0 Visual Studio 2013 C / C ++

时间:2015-08-25 22:34:56

标签: c++ visual-studio visual-studio-2012 openmp

我是新来的,这是我在本网站的第一个问题;

我正在做一个简单的程序来找到矢量c的最大值,它是另外两个矢量a和b的函数。我在Microsoft Visual Studio 2013上进行此操作,问题是它只支持OpenMP 2.0,我无法执行还原操作来直接查找向量的最大值或最小值,因为OpenMP 2.0不支持此操作。 我尝试使用以下代码在没有构造函数缩减的情况下执行此操作:

for (i = 0; i < NUM_THREADS; i++){
    cMaxParcial[i] = - FLT_MAX;
}

omp_set_num_threads(NUM_THREADS);
#pragma omp parallel for private (i,j,indice)
for (i = 0; i < N; i++){
    for (j = 0; j < N; j++){
        indice = omp_get_thread_num();

        if (c[i*N + j] > cMaxParcial[indice]){
            cMaxParcial[indice] = c[i*N + j];
            bMaxParcial[indice] = b[j];
            aMaxParcial[indice] = a[i];
        }
    }
}
cMax = -FLT_MAX;

for (i = 0; i < NUM_THREADS; i++){
    if (cMaxParcial[i]>cMax){
        cMax = cMaxParcial[i];
        bMax = bMaxParcial[i];
        aMax = aMaxParcial[i];
    }

}

我收到错误:&#34;表达式必须包含整数或无范围的枚举类型&#34; 在命令cMaxParcial[indice] = c[i*N + j];

有人可以帮我解决这个错误吗?

2 个答案:

答案 0 :(得分:0)

我不知道您的编译器有什么问题(因为我只能看到您提供的部分数据),代码似乎有效。但是,这有点令人费解,而且不太好。

以下内容如何:

#include <omp.h>
#include <float.h>

extern int N, NUM_THREADS;
extern float aMax, bMax, cMax, *a, *b, *c;

int foo() {
    cMax = -FLT_MAX;
    #pragma omp parallel num_threads( NUM_THREADS )
    {
        float localAMax, localBMax, localCMax = -FLT_MAX;
        #pragma omp for
        for ( int i = 0; i < N; i++ ) {
            for ( int j = 0; j < N; j++ ) {
                float pivot = c[i*N + j];
                if ( pivot > localCMax ) {
                    localAMax = a[i];
                    localBMax = b[j];
                    localCMax = pivot;
                }
            }
        }
        #pragma omp critical
        {
             if ( localCMax > cMax ) {
                 aMax = localAMax;
                 bMax = localBMax;
                 cMax = localCMax;
             }
        }
    }
}

它编译但我没有测试过它...... 无论如何,我避免使用[a-c]MaxParcial数组,因为它们会在线程之间产生错误的共享,从而导致性能不佳。最终的减少是基于critical完成的。它并不理想,但只要你有一个“适度”的线程数就会表现完美。如果你在那里看到一些热点,或者你需要使用“大”数量的线程,那么稍后可以通过适当的并行减少来优化它。

答案 1 :(得分:0)

通常,错误是由其中一个索引不是整数类型引起的。由于您未显示声明ijNindice的代码,我的猜测是N或{{ 1}}是浮点数或双精度数,但如果你提供MCVE,它会更容易回答。但是,它上面的行似乎正确使用了相同的索引。这让我相信它是一个智能感知错误,通常是误报。尝试编译代码并运行它。

现在,关于你还没有问过的问题(为什么我的并行代码比我的串行代码慢?)。您通过使用(可能)连续数组来查找每个线程的a,b和c值,从而导致false sharing。不要对indicepragma使用单个parallel,而是将其拆分为:

for