我有一个简单的Fortran代码,尽管使用了omp_set_num_threads()
子程序,我无法设置线程数,即输出表明我只使用了1个线程。我也尝试了export OMP_NUM_THREADS=4
- 没有结果。
我不知道那些代码有什么问题:
program test
use omp_lib
implicit none
integer :: i, tnr,t
call omp_set_num_threads( 4 )
t = omp_get_num_threads()
write(*,*)'t:',t
!$omp parallel
!$omp do
do i = 1, 20
tnr = omp_get_thread_num()
write( *, * ) 'Thread', tnr, ':', i
end do
!$omp end do
!$omp end parallel
end program test
该代码的输出是:
t: 1
Thread 0 : 1
Thread 0 : 2
Thread 0 : 3
Thread 0 : 4
Thread 0 : 5
Thread 0 : 6
Thread 0 : 7
Thread 0 : 8
Thread 0 : 9
Thread 0 : 10
Thread 0 : 11
Thread 0 : 12
Thread 0 : 13
Thread 0 : 14
Thread 0 : 15
Thread 0 : 16
Thread 0 : 17
Thread 0 : 18
Thread 0 : 19
Thread 0 : 20
感谢您的任何提示!
我使用gentoo linux,gcc-4.5.4编译器激活了openmp
标志。 cpu是移动核心i7第二代。
ldd test:
linux-vdso.so.1 (0x00007fff85fce000)
libgfortran.so.3 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/libgfortran.so.3 (0x00007fe310460000)
libm.so.6 => /lib64/libm.so.6 (0x00007fe310169000)
libgomp.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/libgomp.so.1 (0x00007fe30ff5b000)
libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/libgcc_s.so.1 (0x00007fe30fd45000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe30fb28000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe30f77d000)
librt.so.1 => /lib64/librt.so.1 (0x00007fe30f574000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe310749000)
gfortran -v
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.5.4/gfortran
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.5.4/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.5.4/work/gcc-4.5.4/configure --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.5.4 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.5.4 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.5.4/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.5.4/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4 --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec --disable-fixed-point --without-ppl --without-cloog --disable-lto --enable-nls --without-included-gettext --with-system-zlib --enable-obsolete --disable-werror --enable-secureplt --enable-multilib --enable-libmudflap --disable-libssp --enable-libgomp --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.5.4/python --enable-checking=release --disable-libgcj --enable-languages=c,c++,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-targets=all --with- bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.5.4 p1.0, pie-0.4.7'
Thread model: posix
gcc version 4.5.4 (Gentoo 4.5.4 p1.0, pie-0.4.7)
输出testmp.f140t.optimized(* .statistics之前的那个):
;; Function test (MAIN__)
test ()
{
struct __st_parameter_dt dt_parm.1;
logical(kind=4) D.1545;
struct __st_parameter_dt dt_parm.0;
integer(kind=4) tnr;
integer(kind=4) t;
integer(kind=4) i;
integer(kind=4) i.8;
integer(kind=4) i.7;
integer(kind=4) i.6;
integer(kind=4) tnr.5;
integer(kind=4) i.4;
integer(kind=4) t.3;
<bb 2>:
omp_set_num_threads (&C.1537);
t.3_1 = omp_get_max_threads ();
t = t.3_1;
dt_parm.0.common.filename = &"testmp.f"[1]{lb: 1 sz: 1};
dt_parm.0.common.line = 11;
dt_parm.0.common.flags = 128;
dt_parm.0.common.unit = 6;
_gfortran_st_write (&dt_parm.0);
_gfortran_transfer_character (&dt_parm.0, &"t:"[1]{lb: 1 sz: 1}, 2);
_gfortran_transfer_integer (&dt_parm.0, &t, 4);
_gfortran_st_write_done (&dt_parm.0);
i = 1;
i.4_2 = i;
if (i.4_2 <= 20)
goto <bb 3>;
else
goto <bb 5>;
<bb 3>:
tnr.5_3 = omp_get_thread_num ();
tnr = tnr.5_3;
dt_parm.1.common.filename = &"testmp.f"[1]{lb: 1 sz: 1};
dt_parm.1.common.line = 16;
dt_parm.1.common.flags = 128;
dt_parm.1.common.unit = 6;
_gfortran_st_write (&dt_parm.1);
_gfortran_transfer_character (&dt_parm.1, &"Thread"[1]{lb: 1 sz: 1}, 6);
_gfortran_transfer_integer (&dt_parm.1, &tnr, 4);
_gfortran_transfer_character (&dt_parm.1, &":"[1]{lb: 1 sz: 1}, 1);
_gfortran_transfer_integer (&dt_parm.1, &i, 4);
_gfortran_st_write_done (&dt_parm.1);
i.6_4 = i;
D.1545_5 = i.6_4 == 20;
i.7_6 = i;
i.8_7 = i.7_6 + 1;
i = i.8_7;
if (D.1545_5 != 0)
goto <bb 5>;
else
goto <bb 4>;
<bb 4>:
goto <bb 3>;
<bb 5>:
return;
}
;; Function main (main)
main (integer(kind=4) argc, character(kind=1) * * argv)
{
static integer(kind=4) options.2[8] = {68, 255, 0, 0, 0, 1, 0, 1};
integer(kind=4) D.1552;
<bb 2>:
_gfortran_set_args (argc_1(D), argv_2(D));
_gfortran_set_options (8, &options.2[0]);
test ();
D.1552_3 = 0;
return D.1552_3;
}
答案 0 :(得分:5)
设置OMP_NUM_THREADS
或调用omp_set_num_threads()
会设置 nthreads-var ICV(内部控制变量)。要检索其值,应调用omp_get_max_threads()
而不是omp_get_num_threads()
。
其次,您的代码中存在数据竞争。默认情况下,OpenMP会同时处理tnr
和t
共享变量。在这种情况下,tnr
语句显示的write
的值将是在执行赋值的最后一个线程中获得的值(请注意,当涉及共享变量时,GCC会抑制寄存器优化)。
正确的代码如下:
program test
use omp_lib
implicit none
integer :: i, tnr,t
call omp_set_num_threads( 4 )
t = omp_get_max_threads()
write(*,*)'t:',t
!$omp parallel do private(tnr)
do i = 1, 20
tnr = omp_get_thread_num()
write( *, * ) 'Thread', tnr, ':', i
end do
!$omp end parallel do
end program test
请注意,当do
构造是立即且唯一嵌套在parallel
区域内时,可以使用组合的parallel do
构造并保存两行代码。
您已将Fortran 90代码存储在.f
文件中,因此该文件被识别为固定源格式。在这种情况下,OpenMP指令必须遵守以下规则:
以下哨兵在固定格式的源文件中被识别:
!$omp
|c$omp
|*$omp
Sentinels 必须从第1列开始,并显示为单个字,没有插入字符。 Fortran固定表单行长度,空格,延续和列规则适用于指令行。初始指令行在第6列中必须有空格或零,并且连续指令行在第6列中必须具有空格或零以外的字符。(强调我的)
我猜你的指令与程序代码的其余部分在同一列中开始,因此被简单地视为注释而不是OpenMP指令,这可以从testmp.f.140t.optimized
文件的内容中看出来。
答案 1 :(得分:1)
首先,您必须使用
编译此代码gfortran -fopenmp FILE
第二件事是,omp_get_num_threads()
显示了你所在位置的线程数。当您在串行区域中调用此函数时,答案始终为1
。