我有以下部分代码,我在N = 3000的样本上运行,c ++顺序代码更快3秒,这根本不好。
此代码使用计算值填充数组jsd [N],我想找到最大值及其位置。 所以 1-这个openmp转换是否正确,是否有任何更好的建议,使其更具说服力 2-为什么它等于c ++代码的速度慢,我创建的线程越多,速度越慢。
提前致谢
double maxval = 0;
int pos = -1;
double jsd[N];
#pragma omp parallel for num_threads(4)
for (int i = 0; i < N; i++) {
double Hl = obj.function1(sequenceVctr, i, LEFT);
double Hr = obj.function1(sequenceVctr, i, RIGHT);
jsd[i] = obj.function2(H, i + 1, N, Hl, Hr);
if (jsd[i] >= maxval) {
#pragma omp critical
{
maxval = jsd[i];
pos = i;
}
}
} // for
更新
这是新代码但仍然很慢并且在更多线程中变慢。 我更新代码如下。但是对于更多线程来说仍然会变慢
double maxval = 0;
int pos = -1;
double jsd[N];
#pragma omp parallel num_threads(50)
for (int i = 0; i < N; i++) {
double Hl = obj.function1(sequenceVctr, i, LEFT);
double Hr = obj.function1(sequenceVctr, i, RIGHT);
jsd[i]= obj.function2(H, i + 1, N, Hl, Hr);
} // for
#pragma omp master
{
vector<double> jsd2 (jsd,jsd+N);
vector<double>::iterator jsditer;
jsditer = std::max_element(jsd2.begin(), jsd2.end());
maxval=*jsditer;
pos=std::distance(jsd2.begin(),jsditer) ;
// cout<<"pos"<<pos<<endl;
}
#pragma omp barrier
答案 0 :(得分:3)
我建议的第一个优化是首先计算循环中的所有jsd值,然后通过std::max_element()
找到最大元素。
这样就不会强制线程同步。
我要做的第二件事是转移到英特尔TBB而不是OpenMP并使用parallel_reduce()
。
但最大的问题是,您正在评估的目标函数有多复杂。