我正在尝试使用一个或四个线程来测量并行部分的加速比。由于我的并行部分相对简单,我预计速度接近四倍。 (这是我的问题: openMp: severe perfomance loss when calling shared references of dynamic arrays) 由于我的并行部分在四个核心上的运行速度是两个核心的两倍,我相信我仍然没有找到性能损失的原因。
我想尽可能地并行化我的功能。该函数使用动态数组和私有数量的条目来更改其他动态数组的条目。因为每个迭代步骤仅使用相应循环步骤的数组条目,所以我没有不同的线程访问相同的数组条目。此外,由于访问同一缓存行中的条目,我对错误共享进行了一些考虑。我的猜测是,这是一个次要的影响,因为我的双阵列长度为5 * 10 ^ 5,并且通过为日程安排(动态,块)命令选择合理的块大小,我不希望在极少数情况下进入一个给定的缓存行,由不同的线程同时访问。在我的模拟中,我有大约80个这样的数组,因此在堆栈上分配它们并不舒服,并且为每个线程制作私有副本也是不可能的。 有没有人有想法,如何改善这个?在开始编译器优化之前,我想完全理解为什么这么慢。
让我感到惊讶的是:调用iter(parallel),parallel = false,比调用parallel = true和omp_set_num_threads(1)要慢。
main.cpp中:
int main(){
mathClass m;
m.fillArrays();
double timeCount = 0.0;
for(int j = 0; j<1000; j++){
timeCount += m.iter(true);
}
printf("meam time difference = %fms\n",timeCount);
return 0;
}
mathClass.h:
class mathClass{
private:
double* A;
double* B;
double* C;
int length;
public:
double* D;
mathClass();
double iter(bool parallel);
void fillArrays();
};
mathClass.cpp:
mathClass::mathClass(){
length = 5000000;
A = new double[length];
B = new double[length];
C = new double[length];
D = new double[length];
}
void mathClass::fillArrays(){
int temp;
for ( int i=0; i<length; i++){
temp = rand() % 100;
A[i] = double(temp);
temp = rand() % 100;
B[i] = double(temp);
temp = rand() % 100;
C[i] = double(temp);
}
}
double mathClass::iter(bool parallel){
double startTime;
double endTime;
omp_set_num_threads(4);
startTime = omp_get_wtime();
#pragma omp parallel if(parallel)
{
int alpha; // private in all threads
#pragma omp for schedule(static)
for (int i=0; i<length; i++){
alpha = 15*A[i];
D[i] = C[i]*alpha + B[i]*alpha*alpha;
}
}
endTime = omp_get_wtime();
return endTime - startTime;
}