Fortran派生数据类型二维数组存储

use*_*166 1 fortran fortran90 derived-types

在Fortran中,二维数组以列主格式存储,例如:

integer, allocatable, dimension(:,:)::A
allocate(A(3,4))
Run Code Online (Sandbox Code Playgroud)

数组"A"将作为A(1,1),A(2,1),A(3,1),A(1,2),A(2,2),A(3,2)存储在存储器中),... 等等.

但是当我有一个派生数据类型时会发生什么,例如:

type :: innerdata
 integer :: i
 real :: j       
end type innerdata
type(innerdata), allocatable, dimension(:,:) :: A
allocate(A(3,4))
Run Code Online (Sandbox Code Playgroud)

数组"A"现在如何存储在内存中?谢谢!

Vla*_*r F 5

派生类型数组以相同的列主要顺序存储.

您可能想知道各个组件的存储位置.它们与数组元素的地址的偏移是未指定的,顺序可能与声明的顺序不同,并且它们之间可能存在各种间隙.但是一旦你建立了偏移量的值(通过调用loc()c_loc()),它对于该类型的所有实例都是常量,无论是在该数组内还是在其他任何地方.

因此,组件的顺序可以是

A(1,1)%i,optional_padding,A(1,1)%j,optional_padding,A(2,1)%i,optional_padding,A(2,1)%j,optional_padding,...
Run Code Online (Sandbox Code Playgroud)

但是也

A(1,1)%j,optional_padding,A(1,1)%i,optional_padding,A(2,1)%j,optional_padding,A(2,1)%i,optional_padding,...
Run Code Online (Sandbox Code Playgroud)

通过sequence使用将类型定义为类型

type :: innerdata
 sequence
 integer :: i
 real :: j       
end type innerdata
Run Code Online (Sandbox Code Playgroud)

你可以强制序列

A(1,1)%i,A(1,1)%j,A(2,1)%i,A(2,1)%j,...
Run Code Online (Sandbox Code Playgroud)

但不建议这样做,因为对元素或组件的访问可能较慢,而某些平台可能不允许内存访问未与某些字节数对齐(导致访问速度非常慢).

如果您想知道该类型的存储大小,请使用storage_size()内在函数(Fortran 2008).结果是位.您还可以尝试非标准但常见的扩展函数loc(),该函数提供变量的地址.两个相邻元素的loc的差异是元素大小.使用c_loc()(Fortan 2003)和transfer()结果可以做到同样的事情integer(c_intptr_t).在MPI中,该MPI_Sizeof()功能也可以提供帮助.