【问题标题】:How to implement Structures of Arrays instead of Arrays of Structures in Fortran?如何在 Fortran 中实现数组结构而不是结构数组?
【发布时间】:2016-07-19 14:17:43
【问题描述】:

我正在使用 Fortran 编写关于 CFD 主题的代码。在与一些计算机科学的朋友讨论后,他们告诉我,如果在他/她的代码上实现数组结构 (SoA) 而不是结构数组 (AoS),可以加快计算时间。

关于这个主题的实现,我见过很多例子,但大多数都是用 C 或 C++ 编写的。 (例如https://software.intel.com/en-us/articles/how-to-manipulate-data-structure-to-optimize-memory-use-on-32-bit-intel-architecture)。

谁能告诉我或指导我一些如何在 Fortran 中实现 SoA 而不是 AoS 的基本想法或示例?

【问题讨论】:

    标签: fortran gfortran intel-fortran fortran95


    【解决方案1】:

    这个概念真的没有什么难的。

    而不是

    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 没有任何结构,最自然的处理方式就是声明变量:

    real x(bigN)
    real y(bigN)
    real z(bigN)
    

    您也可以通过这种方式获得数组结构的所有性能优势。对于 Fortranner 来说,有人只知道结构数组,这听起来很奇怪。

    【讨论】:

    • 感谢您的回答。所以假设我应该计算并存储 5 个数组,每个数组包含 100,000 个元素。所以,根据我的经验,我编写了我的代码:而不是使用 2D 可分配数组:A(5,100000) 或 A(100000,5) 我使用了 5 个可分配数组 A、B、C、D、E,每个数组由100,000 个元素(例如 A(100000), ...)我的问题是:在这种情况下我是否执行了 SoA?还是我应该像你以前写的那样写?例如type(struct2) real, dimension(:), allocatable :: A, B, C, D, E end ype type(struct2) :: ARRAYS 非常感谢。
    • 这与多维数组完全无关(几乎)。另见stackoverflow.com/questions/38353768/…
    【解决方案2】:

    (100000,5) 的效果一样好,因为 100000 是连续的。 我可能会这么明确地说,即:

    !DIR$ ATTRIBUTES ALIGN:64                   :: A
    REAL DIMENSION(:.:), ALLOCATABlE, CONTIGUOUS:: A
    

    但该结构也有效。 取决于你喜欢什么。 当 5 在 j (5) 循环上并行化并在连续 I (100000) 循环上矢量化时,这似乎更直观(对我而言)。或执行任务,或其他 !$OMP 工作共享方法。

    如果使用 A,B,C,D,E 而不是 1-5...,您真的不需要结构或数组...

    “The Why”是连续数据可以向量化,因为它是一个数组。 当它是一个结构数组时,您从一个值到下一个值被 5 绑定,并且在任一集合中浪费时间,或者无法对其进行矢量化,或两者兼而有之。

    然后在您的 I-loop (100000) 上,您要么自动矢量化,使用 OMP,要么使用 CilkPlus 外观语句 A(:) = ... 有时矢量符号与 OMP 和自动矢量化一样快,并且有时它比 OMP 慢。您需要同时尝试这两种 (3) 方式,并且 OMP 通常是可靠的,但行数较多且可读性较差。 它应该像 SoA 一样运行得更快

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 2013-07-29
    • 1970-01-01
    相关资源
    最近更新 更多