在使用函数指针时,GSL是否存在线程安全问题?附加的openmp代码使用gsl的gsl_integration_qng函数对于c的各种值在1 <= x <= 2的范围内积分f(x)= - (c + x)^ { - 1}。并行版本的运行速度比串行版本慢得多。我怀疑这与函数指针&amp; fx有关。有没有人有此问题的经验?提前谢谢!
#include<cstdlib>
#include <gsl/gsl_integration.h>
#include<cstdio>
#include<omp.h>
double fx(double x,void *p);
double evalintegral(double c);
using namespace std;
int main(int argc, char *argv[])
{
// numerically integrate the function f(x) = -(c+x)^{-1} between 1 and 2
int Ncs = atoi(argv[1]);
int Nreps = atoi(argv[2]);
printf("Ncs=%d, Nreps=%d.\n",Ncs,Nreps);
int i, j;
double tempF;
double *cs = new double[Ncs];
double dc = 1 / (double)(Ncs-1);
for (i = 0; i < Ncs; i++)
{
cs[i] = dc*(double)i;
}
printf("Began integrations.\n");
#pragma omp parallel for default(none)\
shared(Nreps,Ncs,cs)\
private(i,j,tempF)
for (i = 0; i < Nreps; i++)
{
for (j = 0; j < Ncs; j++)
{
tempF = evalintegral(cs[j]);
}
}
delete[] cs;
printf("Finished integrations.\n");
return 0;
}
double fx(double x, void *p)
{
double *c = (double*) p;
return -1 / (*c + x);
}
double evalintegral(double c)
{
double *ptr_c = new double[1];
ptr_c[0] = c;
gsl_function Fquad;
Fquad.params = ptr_c;
Fquad.function = &fx;
size_t quadneval;
double quadres, quaderr;
gsl_integration_qng(&Fquad,1,2,1e-10,1e-6,&quadres,&quaderr,&quadneval);
delete[] ptr_c;
return quadres;
}
答案 0 :(得分:0)
我遇到了GSL积分例程的相同问题。正如@mrx_hk提到的,问题是重复使用工作空间对象。 就我而言,我存储:
gsl_integration_workspace * w_ = gsl_integration_workspace_alloc(1200);
作为类成员变量,并在每次集成调用时重新使用存储,这导致了竞争状况。 解决方案是为每个线程创建一个工作区对象,在我的情况下,是为每个集成调用创建一个工作区对象。