如何在Fortran中实现数组结构而不是结构数组?

如何在Fortran中实现数组结构而不是结构数组?,fortran,gfortran,intel-fortran,fortran95,Fortran,Gfortran,Intel Fortran,Fortran95,我正在用Fortran编写CFD主题的代码。在与一些计算机科学的朋友讨论后,他们告诉我,如果在代码上实现阵列结构(SoA)而不是结构阵列(AoS),可以加快计算速度 关于这个主题的实现,我看到了很多例子,但是大多数例子都是C或C++。(例如) 有没有人能给我展示或指导一些基本的想法或示例,如何在Fortran中实现SoA而不是AoS?这个概念其实并不难 而不是 type struct real x, y, z end type type(struct), allocatable :: ar

我正在用Fortran编写CFD主题的代码。在与一些计算机科学的朋友讨论后,他们告诉我,如果在代码上实现阵列结构(SoA)而不是结构阵列(AoS),可以加快计算速度

关于这个主题的实现,我看到了很多例子,但是大多数例子都是C或C++。(例如)


有没有人能给我展示或指导一些基本的想法或示例,如何在Fortran中实现SoA而不是AoS?

这个概念其实并不难

而不是

type struct
  real x, y, z
end type

type(struct), allocatable :: array(:)
你用

type(struct2)
  real, dimension(:), allocatable :: x, y, z
end ype

type(struct2) :: arrays

这只是一个C或C++示例逐行翻译。尽管Fortran使用了其他语言作为示例,但关于本主题的所有内容或多或少都适用于Fortran

实际上,在过去,Fortran没有任何结构,最自然的方法就是声明变量:

real x(bigN)
real y(bigN)
real z(bigN)
通过这种方式,您也可以获得阵列结构的所有性能优势。对于一个Fortranner来说,有人只知道结构的数组,这听起来几乎很奇怪。

因为100000是连续的,所以(100000,5)也同样有效。 我可能会这么明确地说,即:

!DIR$ ATTRIBUTES ALIGN:64                   :: A
REAL DIMENSION(:.:), ALLOCATABlE, CONTIGUOUS:: A
但这种结构也起作用。 取决于你喜欢什么。 (对我来说)当5是一个更大的数字,在j(5)循环上并行,在连续的I(100000)循环上矢量化时,这看起来更直观。或做任务,或其他$OMP工作共享方法

实际上,如果使用a、B、C、D、E而不是1-5,则不需要结构或数组

“原因”是连续数据可以矢量化,因为它是一个数组。 当它是一个结构数组时,从一个值到下一个值由5绑定,并在其中一个聚集中浪费时间,或者无法将其矢量化,或者两者兼而有之

然后在I-loop(100000)上,您可以自动矢量化、使用OMP或使用一个看起来像CilkPlus的语句a(:)=。。。有时向量表示法与OMP和自动向量化一样快,有时比OMP慢。您需要尝试两种(3)方法,OMP通常是实心的,但多了几行,可读性较差。
作为SoA,它应该运行得更快

谢谢你的回答。假设我应该计算并存储5个数组,每个数组由100000个元素组成。因此,根据我的经验,我编写了我的代码:我没有使用2D可分配数组:A(5100000)或A(100000,5),而是使用了5个可分配数组A、B、C、D、E,每个数组由100000个元素组成(例如A(100000),…),我的问题是:在这种情况下我是否执行了SoA?还是我应该像你以前写的那样写作?e、 类型(struct2)real,维度(:),可分配::A,B,C,D,e结束类型(struct2)::数组非常感谢。这与多维数组毫无关系(几乎)。也可以看到,这是一个答案,这一个或那一个问题的标题。考虑一下回答吧。在这里,你可能至少应该处理一点数组的结构和数组的结构。而且,请,请,请不要教人们
kind=4
,当它没有在问题中使用时。别这样。我有时只出于这个原因就倾向于按下向下投票按钮。在这种情况下使用刚才的代码>实际< /COD>完全可以。