3

I'm writing my code on CFD topic with Fortran. After discussing with some friends from computer science, they told me that one could speed up the computation time if one implements Structures of Arrays (SoA) instead of Arrays of Structures (AoS) on his/her code.

There are many examples I've seen about this topic's implementation, but most of them are in C or C++. (e.g. https://software.intel.com/en-us/articles/how-to-manipulate-data-structure-to-optimize-memory-use-on-32-bit-intel-architecture).

Could anyone show me or guide me some basic ideas or examples how to implement SoA instead of AoS in Fortran?

francescalus
  • 30,576
  • 16
  • 61
  • 96
bestrong
  • 151
  • 10

2 Answers2

3

There is really nothing difficult about this concept.

Instead of

type struct
  real x, y, z
end type

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

you use

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

type(struct2) :: arrays

It is really just a line by line translation of a C or C++ example. More or less everything what you can read about this topic is still applicable to Fortran even if they use other language for their examples.

Actually, in the old days Fortran didn't have any structures and the most natural way how to do stuff was just to declare variables:

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

and you get all those performance benefits of structures of arrays this way too. It sounds almost strange to a Fortranner that someone knows only arrays of structures.

  • Thanks for the answer. So let's say I should calculate and store 5 arrays which consist of 100,000 elements each . So, on my experience, I had written my code: instead of using 2D allocatable arrays: A(5,100000) or A(100000,5) I used 5 allocatable arrays A, B, C, D, E which each consists of 100,000 elements (e.g. A(100000), ... ) My question is: Have I performed the SoA in this case? Or should I still write like you wrote me before? e.g. type(struct2) real, dimension(:), allocatable :: A, B, C, D, E end ype type(struct2) :: ARRAYS Many thanks. – bestrong Jul 19 '16 at 14:46
  • This has nothing to do with multidimensional arrays at all (almost). Also see http://stackoverflow.com/questions/38353768/are-1d-arrays-faster-than-2d-arrays-due-to-column-major-order – Vladimir F Героям слава Jul 19 '16 at 14:51
0

The (100000,5) works just as good because the 100000 are contiguous. I would probably say so explicitly, I.e.:

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

But the structure also works. Depends on what you prefer. It seems more intuitive ( to me ) when the 5 is a larger number to parallelise on the j (5) loop, and vectorise on the contiguous I (100000) loop. Or do task, or other !$OMP workshare approaches.

Really you do not need a structure or array if A,B,C,D,E are used instead of 1-5...

"The Why" is that the contiguous data can be vectorized because it is an array. when it is an array of structures you bound by 5 from value to the next, and lose time in either gathers, or not being able to have it vectorized, or both.

Then On your I-loop (100000) you either auto-vectorise, use OMP, or use a CilkPlus looking statement A(:) = ... Sometimes the vector notation is just as fast as OMP and auto vectorised, and sometimes it is slower than OMP. You need to try it both (3) ways, and the OMP usually is solid, but a few more lines and less readable. It should run a lot faster as SoA

Holmz
  • 714
  • 7
  • 14
Holmz
  • 51
  • 2
  • That is more an answer to this one http://stackoverflow.com/questions/38353768/are-1d-arrays-faster-than-2d-arrays-due-to-column-major-order or http://stackoverflow.com/questions/38353830/how-to-choose-the-best-configuration-of-2d-array-ai-j that the question in the title. Consider answering there instead. Here you should probably tackle structures of arrays and arrays of structures at least a little. – Vladimir F Героям слава Jul 20 '16 at 16:34
  • And, please, please, please do not teach people `kind=4` when it wasn't used in the question. Just don't. I am sometimes inclined to press the downvote button for that reason alone. Consider http://stackoverflow.com/a/856243/721644 In this case using just `real` is completely fine. – Vladimir F Героям слава Jul 20 '16 at 16:36