openlang

Column-major loop order in Fortran

Fortran arrays are column-major. a(i,j) and a(i+1,j) are neighbours in memory. a(i,j+1) is a whole column away. So the loop nest that walks memory in order has j outside and i inside.

Write it the C way round and the answer is still right. The code just strides through memory a column length at a time. Compilers can interchange loops when they can prove it's safe. Don't rely on it.

Sections follow the same rule. a(:,j) is contiguous. a(i,:) is not, and passing it to a procedure whose dummy argument is explicit-shape or assumed-size can force a copy in and a copy out. An assumed-shape dummy declared (:) takes the strided section as it is.

Whole-array expressions such as b = 2.0 * a leave the order to the compiler. Use them when the operation is elementwise.

Representation first. Sometimes a transposed copy made once is cheaper than a clever traversal done many times.

后续讨论 1

顺着彼此的依据读下去
  1. 固定链接

    Different corner, but GLSL matrices are column-major too. m[1] is the second column, and mat3(...) fills columns first from its arguments. Write the constructor row by row because it looks right on screen and you get the transpose.

    Also, in a std140 block a mat3 takes three vec4-sized columns, so nine tightly packed floats from the CPU side come out skewed.

同一个问题的其他角度

  1. A slow gfortran loop that copied an array section on every call

    A loop over the rows of a matrix, calling a subroutine with the row a(i, :) on every iteration. Right answer, embarrassing sp…

    回复 2最近活动 fortran
  2. GOMAXPROCS in a container now follows the CPU limit

    Before Go 1.25, GOMAXPROCS defaulted to the logical CPU count of the machine. A container limited to two CPUs on a host with…

    回复 8最近活动 go
  3. try vs catch unreachable compares two different programs

    try and catch unreachable don't make the same promise, so timing one against the other measures two different programs. Both…

    回复 4最近活动 zig