誰なのか実は知らない ....
                            ↓
             〈コソッとじゃないそうです、本人談によると。〉
               ↓
 Web の世界って面白いな〜、コソっと書いてあることでも、google が引っ掛けてしまう。
さて、とあるプログラム の中で 多次元配列を使ってない ことについて、キーワード

                 vertex ctmrg ising

で引っ掛かるものを見つけてしまった。ここに書いてあること、マトモである。下の4行の
メッセージも守る方が良い。でも、ちょっと残念なのが「一番実行時間のかかるルーチンで
キャッシュ効率の良いメモリーアクセスを発生させる」ことを考えてたのだけど、一番実行
時間のかからないルーチンについて言及されている所。まあ、サブルーチン側では行列表現
しなさい、というのは良いかもね、行列演算を検出するコンパイラに運良く当たれば高速に
処理してくれるから。

 で、その、メモリーアクセスの問題だけど、例えば A(L,k,j,i) という行列があって、添字
がそれぞれ NL, Nk, Nj, Ni だけ回るとしよう。素直にループを回すなら

   do i = 0, Ni-1; do j = 0, Nj-1; do k = 0, Nk-1; do l = 0, NL-1

と do ループを並べることになる。が.... Ni = 10000, Nj = Nk = NL = 2 だと? 最近のコンパ
イラは用心深く「内側以外のループが最長である場合も考えてコード生成する」ので、たぶ
ん i のループを連続して回して、8 変数おきのメモリー・アクセスを実行させるようになる
だろう。これがイヤだったら、予めどこかで添字の入れ替えを行なう目的で

   B(i,L,k,j) = A(L,k,j,i)

という代入を書いておかなければならない。もう少し複雑なパターンもあって、

   C(j,k,x,d,e,f) = C(j,k,x,d,e,f) + A(i,j,k,L,x,y) B(d,i,e,L,f,y)

なんて演算が現れたとしよう。できれば、こんな難儀な物は紙とエンピツで落としておきた
いのだけど、多次元配列を「実質的には複数の足をまとめた行列として扱う。また、行列と
しての足のまとめ方は場所によって変化する」という使い方が避けられない場合も実際には
良く出くわすのだ。上の例では、まず A と B を 行列 (〜2 次元配列) 化しないといけない。

   A(i,j,k,L,x,y) → A'(i,k,x, j,L,y)   B(d,i,e,L,f,y) → B'(d,e,f, i,L,y)

この下準備をしておけば、C を「行列」 A' と B' の縮役で簡単に得ることができる。まあ、
B' の足の順番をどうするかは好みの問題で、逆にしておけば C = A'B' とか C = B'A' など、
標準的な書き方もできる。こういう変換がボコボコ出て来ると、配列変換の為にいちいち
do ループを切るのがイヤになって来るというのが本音。で、どう「解決」したかというと、
1 次元配列だけを使って、必要に応じて次のような「上位・下位入れ替えルーチン」を複数
回呼ぶことにした。

cccccc
      subroutine exchg2( m1, m2,         A,      B    )
      integer      i, j, m1, m2; real(8) A(0:*), B(0:*)
      do i = 0, m1-1
      do j = 0, m2-1;    B(j*m1+i) = A(i*m2+j)
      end do; end do; end
cccccc
      subroutine exchg3(  m1, m2, m3,         A,      B    )
      integer       i, j, m1, m2, m3; real(8) A(0:*), B(0:*)
      do i = 0, m1-1
      do j = 0, m2-1;  B((j*m1+i)*m3:(j*m1+i)*m3 + m3-1) 
     &               = A((i*m2+j)*m3:(i*m2+j)*m3 + m3-1)
      end do; end do; end


アセンブラでは、良くお目にかかる処理ですよね。もちろん、コレを使ってしまうと、書い
た本人しかわからないプログラムになる。わっはっは〜?! 

.... というパイプライン的発想は、最近では流行らないかな、みんなパラパラだもんネ。