Gcc 使用GSL和OpenMP编译

Gcc 使用GSL和OpenMP编译,gcc,openmp,gsl,Gcc,Openmp,Gsl,在编译/编写makefile方面,我不是最好的 我正在尝试编写一个同时使用GSL和OpenMP的程序 我单独使用GSL和OpenMP没有问题,但我在使用两者时遇到了问题。例如,我可以编译GSL程序 通过打字 $gcc -c Bessel.c $gcc Bessel.o -lgsl -lgslcblas -lm $./a.out 它是有效的 我还能够编译使用OpenMP的程序,我在这里找到了: 在这种情况下,我打字 $gcc -fopenmp test_omp.c $./a.out 我得到了

在编译/编写makefile方面,我不是最好的

我正在尝试编写一个同时使用GSL和OpenMP的程序

我单独使用GSL和OpenMP没有问题,但我在使用两者时遇到了问题。例如,我可以编译GSL程序 通过打字

$gcc -c Bessel.c
$gcc Bessel.o -lgsl -lgslcblas -lm
$./a.out
它是有效的

我还能够编译使用OpenMP的程序,我在这里找到了:

在这种情况下,我打字

$gcc -fopenmp test_omp.c
$./a.out
我得到了我想要的(我所有的4个线程都被使用了)

然而,当我简单地编写一个结合了这两个代码的程序时

#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>
#include <omp.h> 

 int
 main (void)
 {
   double x = 5.0;
   double y = gsl_sf_bessel_J0 (x);
   printf ("J0(%g) = %.18e\n", x, y);


int dimension = 4;
int i = 0;
int j = 0;
#pragma omp parallel private(i, j)
for (i =0; i < dimension; i++)
    for (j = 0; j < dimension; j++)
        printf("i=%d, jjj=%d, thread = %d\n", i, j, omp_get_thread_num());

return 0;

 }

GSL部分工作(计算贝塞尔函数),但OpenMP部分仅使用一个线程。我不确定这里出了什么问题…

我想,将变量
I
j
声明为共享是不正确的。试着将它们声明为私有。否则,每个线程将获得相同的
j
,并且
j++
将在线程之间生成争用条件。

您错过了OpenMP部件中
的工作共享指令
。应该是:

// Just in case GSL modifies the number of threads
omp_set_num_threads(omp_get_max_threads());
omp_set_dynamic(0);

#pragma omp parallel for private(i, j)
for (i =0; i < dimension; i++)
    for (j = 0; j < dimension; j++)
        printf("i=%d, jjj=%d, thread = %d\n", i, j, omp_get_thread_num());
//以防GSL修改线程数
omp_set_num_threads(omp_get_max_threads());
omp_集_动态(0);
#pragma omp并行专用(i,j)
对于(i=0;i

编辑:为了总结下面评论中的讨论,OP未能在编译阶段提供
-fopenmp
。这使GCC无法识别OpenMP指令,因此没有生成并行代码。

由于user1202136指出了我在原始代码中犯的错误,我已在编辑中更正了该错误。我仍然有同样的问题,但这也不起作用。如果我运行上面的代码并删除GSL部分来计算Bessel函数,那么当我使用$gcc-fopenmp omp_test.c编译时,它就会工作。然而,当我使用GSL并尝试按照上面描述的方式编译时,只使用了1个线程。这似乎纯粹是一个编译语法的问题,但仍然不起作用。我认为这与我在编译时在命令提示符中键入的内容有关……请参阅我最初的博文末尾,如果我编写的程序只执行上面编写的代码,而不执行小的GSL计算,那么我可以使用:$gcc-fopenmp omp_test.c进行编译。然而,当我使用GSL时,我需要正确地链接所有库,我尝试的是我原始帖子中的三行,但这不起作用
-llib
链接库
liblib.so
libliblib.a
-fopenmp
是一个编译器指令,它在GCC中支持OpenMP。这些是不同的事情,您的做法是正确的,至少在编译/链接部分是这样。因为您必须在编译源文件时启用OpenMP支持,否则编译器将忽略所有OpenMP指令,并且不会生成并行代码。如果您在未启用OpenMP支持的情况下编译OpenMP代码,英特尔的
icc
编译器将为您提供无法识别的杂注警告<代码>gcc
显然没有。
// Just in case GSL modifies the number of threads
omp_set_num_threads(omp_get_max_threads());
omp_set_dynamic(0);

#pragma omp parallel for private(i, j)
for (i =0; i < dimension; i++)
    for (j = 0; j < dimension; j++)
        printf("i=%d, jjj=%d, thread = %d\n", i, j, omp_get_thread_num());