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"现在如何存储在内存中?谢谢!
派生类型数组以相同的列主要顺序存储.
您可能想知道各个组件的存储位置.它们与数组元素的地址的偏移是未指定的,顺序可能与声明的顺序不同,并且它们之间可能存在各种间隙.但是一旦你建立了偏移量的值(通过调用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()功能也可以提供帮助.