我有一个 Fortran 模块,我想尽可能地遵循 OOP 理念来组织它,同时仍然使其与 Fortran 2003 兼容。这个模块基本上:(a)分配/释放临时数组缓冲区,以及(b)提供一个函数 do_F对一些数据进行操作。这个函数 do_F 使用这些临时缓冲区,但也依赖于几个辅助类型。
我很清楚我应该将缓冲区放入一个类型中,并在适当的时候初始化/释放。但是,由于对 do_F 的每次调用都需要几个参数,所以我确信最好使用的设计策略是什么。
更具体地说,考虑以下实现:
每次调用 do_F 时传递大量类型
type object_t ! lots of private buffers real, allocatable :: buf1(:,:,:), buf2(:,:,:), etc. end type object_t subroutine init_object(this) type(object_t), intent(INOUT) :: this allocate( this%buf1(..., ..., ...) ) !... end subroutine init_object subroutine do_F(this, data, aux1, aux2, ..., auxN) type(object_t), intent(INOUT) :: this type(data_t), intent(INOUT) :: data type(aux1_t), intent(IN) :: aux1 !... !do stuff on data using the buffers and values stored ! in aux1 .. auxN end subroutine do_F
保存指向 do_F 需要的类型的指针
type object_t ! lots of private buffers real, allocatable :: buf1(:,:,:), buf2(:,:,:), etc. ! pointers to auxiliary types type(aux1_t), pointer :: aux1_ptr !... end type object_t subroutine init_object(this, aux1, aux2, ..., auxN) type(object_t), intent(INOUT) :: this type(aux1_t), intent(IN), target :: aux1 !... allocate( this%buf1(..., ..., ...) ) !... this%aux1_ptr => aux1 !... end subroutine init_object subroutine do_F(this, data) type(object_t), intent(INOUT) :: this type(data_t), intent(INOUT) :: data !do stuff on data using the buffers and values stored ! in this%aux1_ptr .. this%auxN_ptr end subroutine do_F
我的具体问题是:
- 实施 #2 有效吗?PGI编译器没有抱怨,但听说函数返回后intent(IN)不再定义好
- 将此方案与指针一起使用是否会降低性能?即使我不写入这些 aux_ptr,编译器是否能够像 #1 一样优化我的代码?
一些注意事项:
- 函数 do_F 被调用了大约 100 次,每次调用都需要几分钟,并且对大型数组进行操作。
- 除了 do_F 之外,还有 do_G 和 do_H 函数对相同的数据进行操作并使用相同的辅助变量。这就是为什么我想首先减少传递给函数的变量数量。
- 我不想将所有辅助变量组合成一种类型,因为它们在大型 HPC 代码的其余部分中使用。
谢谢!