GSL线程安全问题

时间:2016-04-29 13:46:08

标签: c++ multithreading thread-safety openmp gsl

在使用函数指针时,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;
}

1 个答案:

答案 0 :(得分:0)

我遇到了GSL积分例程的相同问题。正如@mrx_hk提到的,问题是重复使用工作空间对象。 就我而言,我存储:

gsl_integration_workspace * w_ = gsl_integration_workspace_alloc(1200);

作为类成员变量,并在每次集成调用时重新使用存储,这导致了竞争状况。 解决方案是为每个线程创建一个工作区对象,在我的情况下,是为每个集成调用创建一个工作区对象。