测试类型的内部表示(种类)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测试类型的内部表示(种类)相关的知识,希望对你有一定的参考价值。
当使用不同的内部表示(种类)测试计算机性能时,代码保持或多或少相同,除了测试参数的定义(kind = 1; kind = 2)。我试图建立不同的模块。
module var_1
implicit none
real(8), allocatable :: x(:,:),xi(:,:),xt(:,:)
integer(kind=1), allocatable :: z(:,:)
end module var_1
module var_2
implicit none
real(8), allocatable :: x(:,:),xi(:,:),xt(:,:)
integer(kind=2), allocatable :: z(:,:)
end module var_2
还有一个全局模块定义了不会改变的参数:
module global
integer :: i,j,n,p,nProcessors,s,v,w,infodpotrf,infodpotri,mkl_get_max_threads
integer, dimension(3) :: ni = [100, 1000, 10000], pi = [100, 1000, 10000]
integer, dimension(5) :: nProcessorsi = [1, 2, 4, 6, 12]
real(8):: u,myone= 1.d0,t11,t22
real:: t2,t1
include 'omp_lib.h'
end module global
比在程序部分,我们调用后面定义的子程序:
program test
call matrix_multi_inv_1
call matrix_multi_inv_2
end program test
子程序:
subroutine matrix_multi_inv_1
use global
use var_1
open (unit=100,file="results.txt",status="unknown")
do s=1,5
nProcessors = nProcessorsi(s)
CALL OMP_SET_NUM_THREADS(nProcessors)
do v=1,3
n=ni(v)
do w=1,3
p=pi(w)
allocate(x(n,n),z(n,p),xi(n,n),xt(n,n))
do i=1,n
do j=1,p
call random_number(u)
z(i,j)=real(floor(u*3),8)
enddo
enddo
1000 format(3(a20),2(i10),2(f15.3),i10)
t11=omp_get_wtime()
call cpu_time(t1)
x=matmul(z,transpose(z))
t22=omp_get_wtime()
call cpu_time(t2)
write(100,1000) 'x_integer_kind_1', 'G_real_8', 'matmul', n, p, t22-t11,t2-t1, mkl_get_max_threads()
deallocate(x,z,xi,xt)
enddo
enddo
enddo
end subroutine matrix_multi_inv_1
subroutine matrix_multi_inv_2
use global
use var_1
open (unit=100,file="results.txt",status="unknown")
do s=1,5
nProcessors = nProcessorsi(s)
CALL OMP_SET_NUM_THREADS(nProcessors)
do v=1,3
n=ni(v)
do w=1,3
p=pi(w)
allocate(x(n,n),z(n,p),xi(n,n),xt(n,n))
do i=1,n
do j=1,p
call random_number(u)
z(i,j)=real(floor(u*3),8)
enddo
enddo
1000 format(3(a20),2(i10),2(f15.3),i10)
t11=omp_get_wtime()
call cpu_time(t1)
x=matmul(z,transpose(z))
t22=omp_get_wtime()
call cpu_time(t2)
write(100,1000) 'x_integer_kind_2', 'G_real_8', 'matmul', n, p, t22-t11,t2-t1, mkl_get_max_threads()
deallocate(x,z,xi,xt)
enddo
enddo
enddo
end subroutine matrix_multi_inv_2
这就是问题所在。除了调用模块部分之外,子例程完全相同。我试图在子例程中使用包含语句,但如果调用内部子例程,则这不起作用。我也尝试使用带有属性的子程序,但我的编译器报告错误:
类型参数必须是编译时常量。
有谁知道如何优化代码的好方法。当测试10个不同的内部表示的不同变化时,这个代码变得太大了。
答案
类似的问题通常由使用include`的穷人模板解决。您将公共部分移动到另一个文件,然后就可以了
subroutine matrix_multi_inv_1
use var_1
include "common.f90"
end subroutine
subroutine matrix_multi_inv_2
use var_2
include "common.f90"
end subroutine
C预处理器可用于更多功率。
另一答案
为什么不将相关代码导入文件print_huge.inc.F90
以包含在模块中:
! No module ... required
interface print_huge
module procedure print_huge
end interface
contains
subroutine print_huge(a)
real(kind=mykind),intent(in) :: a
print *, huge(a)
end subroutine
! no end module
然后你可以将include
这个变成不同的模块print_huge_N
:
module print_huge_4
integer,parameter :: mykind = 4
include 'print_huge.inc.F90'
end module
module print_huge_8
integer,parameter :: mykind = 8
include 'print_huge.inc.F90'
end module
module print_huge_16
integer,parameter :: mykind = 16
include 'print_huge.inc.F90'
end module
注意,每个模块都有自己定义的mykind
!
为方便起见,您可以使用定义的接口将模块捆绑成一个“超级模块”(灵感来自Arjen Markus一书中的示例):
module print_huge_all
use print_huge_4
use print_huge_8
use print_huge_16
end module
然后您的主要应用程序将看起来像:
program huge_program
use print_huge_all
real(kind=4) :: a1
real(kind=8) :: a2
real(kind=16) :: a3
call print_huge(a1)
call print_huge(a2)
call print_huge(a3)
end program
使用以下输出:
./a.out
3.40282347E+38
1.7976931348623157E+308
1.18973149535723176508575932662800702E+4932
子例程驻留在包含文件中,不需要调整到所有kind
s。当然,您可以直接访问所有模块和/或使用=>
运算符“重命名”子例程。
以上是关于测试类型的内部表示(种类)的主要内容,如果未能解决你的问题,请参考以下文章