0

我有一个 Fortran 模块,我想尽可能地遵循 OOP 理念来组织它,同时仍然使其与 Fortran 2003 兼容。这个模块基本上:(a)分配/释放临时数组缓冲区,以及(b)提供一个函数 do_F对一些数据进行操作。这个函数 do_F 使用这些临时缓冲区,但也依赖于几个辅助类型。

我很清楚我应该将缓冲区放入一个类型中,并在适当的时候初始化/释放。但是,由于对 do_F 的每次调用都需要几个参数,所以我确信最好使用的设计策略是什么。

更具体地说,考虑以下实现:

  1. 每次调用 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
    
  2. 保存指向 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
    

我的具体问题是:

  1. 实施 #2 有效吗?PGI编译器没有抱怨,但听说函数返回后intent(IN)不再定义好
  2. 将此方案与指针一起使用是否会降低性能?即使我不写入这些 aux_ptr,编译器是否能够像 #1 一样优化我的代码?

一些注意事项:

  1. 函数 do_F 被调用了大约 100 次,每次调用都需要几分钟,并且对大型数组进行操作。
  2. 除了 do_F 之外,还有 do_G 和 do_H 函数对相同的数据进行操作并使用相同的辅助变量。这就是为什么我想首先减少传递给函数的变量数量。
  3. 我不想将所有辅助变量组合成一种类型,因为它们在大型 HPC 代码的其余部分中使用。

谢谢!

4

1 回答 1

2

如果 Intent IN 变量在调用之前,它们在返回之后定义良好。该程序不允许更改它们。一个例外是指针变量的值,您可以在其中更改目标的值,但不能更改intent(IN)指针虚拟参数的指针的关联状态。

我不确定效率。快速阅读后,第 2 版看起来更好。

于 2012-04-20T05:45:00.207 回答