这样使用pragma omp simd正确吗? #包括 #包括 #包括 #定义功率(x)((x)*(x)) #定义NUM_线程8 #定义wmax 1000 #定义NV2 #定义n5 int b=0; 浮点[N][Nv]={0,1}、{3,4}、{1,2}、{5,1}、{8,9}; 浮点长度[wmax+1]={0}; 浮动EuclDist(浮动*Ne,浮动*Pe){ int i; 浮点数s=0; 对于(i=0;i
似乎是最快的,但是这样使用SIMD正确吗 首先,有一个争用条件需要固定,即在更新数组这样使用pragma omp simd正确吗? #包括 #包括 #包括 #定义功率(x)((x)*(x)) #定义NUM_线程8 #定义wmax 1000 #定义NV2 #定义n5 int b=0; 浮点[N][Nv]={0,1}、{3,4}、{1,2}、{5,1}、{8,9}; 浮点长度[wmax+1]={0}; 浮动EuclDist(浮动*Ne,浮动*Pe){ int i; 浮点数s=0; 对于(i=0;i,c,parallel-processing,openmp,simd,C,Parallel Processing,Openmp,Simd,似乎是最快的,但是这样使用SIMD正确吗 首先,有一个争用条件需要固定,即在更新数组length[b]期间。此外,您正在访问数组a;(从1迭代到N+1),并且正在传递&a[i]。您可以使用OpenMPreduce子句修复争用条件: #include <stdio.h> #include <stdlib.h> #include <omp.h> #define pow(x) ((x) * (x)) #define NUM_THREADS 8 #define wm
length[b]
期间。此外,您正在访问数组a
;(从1
迭代到N+1
),并且正在传递&a[i]
。您可以使用OpenMPreduce
子句修复争用条件:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#define pow(x) ((x) * (x))
#define NUM_THREADS 8
#define wmax 1000
#define Nv 2
#define N 5
int b=0;
float Points[N][Nv]={ {0,1}, {3,4}, {1,2}, {5,1} ,{8,9}};
float length[wmax+1]={0};
float EuclDist(float* Ne, float* Pe) {
int i;
float s = 0;
for (i = 0; i < Nv; i++) {
s += pow(Ne[i] - Pe[i]);
}
return s;
}
void DistanceFinder(float* a[]){
int i;
#pragma omp simd
for (i=1;i<N+1;i++){
length[b] += EuclDist(&a[i],&a[i-1]);
}
//printf(" %f\n", length[b]);
}
void NewRoute(){
//some irrelevant things
DistanceFinder(Points);
}
int main(){
omp_set_num_threads(NUM_THREADS);
do{
b+=1;
NewRoute();
} while (b<wmax);
}
因为我使用的是以前的迭代(I和I-1)
在您的例子中,这是可以的,因为数组a
刚刚被读取
我看到的结果是正确的还是错误的
很有可能没有发生矢量化。无论如何,由于前面提到的竞争条件,它仍然是未定义的行为
您可以简化代码,以增加实际发生矢量化的可能性,例如:
#pragma omp declare simd uniform(Ne, Pe)
float EuclDist(float* Ne, float* Pe) {
int i;
float s = 0;
for (i = 0; i < Nv; i++)
s += pow(Ne[i] - Pe[i]);
return s;
}
#pragma omp declare simd uniform(Ne, Pe)
float EuclDist(float* Ne, float* Pe) {
int i;
float s = 0;
for (i = 0; i < Nv; i++)
s += pow(Ne[i] - Pe[i]);
return s;
}
void DistanceFinder(float* a[]){
int i;
float sum = 0;
float tmp;
#pragma omp simd private(tmp) reduction(+:sum)
for (i=1;i<N;i++){
tmp = pow(a[i][0] - a[i-1][0]) + pow(a[i][1] - a[i-1][1])
sum += tmp;
}
length[b] += sum;
}
void DistanceFinder(float a1[], float a2[]){
int i;
float sum = 0;
float tmp;
#pragma omp simd private(tmp) reduction(+:sum)
for (i=1;i<N;i++){
tmp = pow(a1[i] - a1[i-1]) + pow(a2[i][1] - a2[i-1][1])
sum += tmp;
}
length[b] += sum;
}