我是新来的,这是我在本网站的第一个问题;
我正在做一个简单的程序来找到矢量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];
有人可以帮我解决这个错误吗?
答案 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)
通常,错误是由其中一个索引不是整数类型引起的。由于您未显示声明i
,j
,N
和indice
的代码,我的猜测是N
或{{ 1}}是浮点数或双精度数,但如果你提供MCVE,它会更容易回答。但是,它上面的行似乎正确使用了相同的索引。这让我相信它是一个智能感知错误,通常是误报。尝试编译代码并运行它。
现在,关于你还没有问过的问题(为什么我的并行代码比我的串行代码慢?)。您通过使用(可能)连续数组来查找每个线程的a,b和c值,从而导致false sharing。不要对indice
和pragma
使用单个parallel
,而是将其拆分为:
for