概要
MN-Core2でソートを行うコードの需要が存在しうるということを風の噂で聞いたので、最短の方法を探しています。足掛かりとして、各PE内でdouble型の64要素をソートしてみました。
制約
霞から取り出したものなので、他のものも考えるつもりではいます。
入出力
LM0の入力をソートし、LM1に降順で出力
$lm[0:128] → $ln[0:128]
値のみをソートし、キー(連想配列)などは気にしない。
比較・転送
ALUのdmax, dminの両命令を使用して比較、与えられた各要素のビット列は変更しない。
dmax, dminは、±∞やNaNを下位ビットで区別してくれます。一方で、非正規化数の範囲と±0とは全て同一の値として扱われます。
この性質上、キーがなくても安定ソートかどうかで結果が変わりうるのですが、今回は気にしないことにします。
MAUのdvaddを使って比較することもできるのですが、正規化数同士の比較でも、差が非正規化数になって失敗しうること、NaNを∞と同様に扱ってしまうことなど、ALU命令に比してもさらに緩いので、今回は使いません。
Sorting Network
ソートアルゴリズムにもいろいろありますが、MN-Coreは普通のCPUなんかと勝手が違うので、特性を把握したうえで相性のよいものを選びます。
128要素以上についてはまた記事を改めますが、64要素以下ではSorting Networkが最も優秀であると思います。
Sorting Networkの中にも種類がありますが、性能と、他のアルゴリズムと接ぐのに都合がよいことから、Batcher Odd-Even Merge Sortを使うことにしました。以下その前提で話を進めます。
Batcherのレポート
余談ですが、このレポート面白いので、お時間があれば読んでみてください。58年前のコンピュータにおける優先順位がよく表れていると思います。特に、値をMSBからシリアルに流して、比較を行わせるというアイデアは、言われてみれば納得なのですが、まだまだ回路が高価だった時代を偲ばせます。1ビット進めるのに40nsらしいですが、1968年のECLはもう少し速くできるはずなので、安めのものか、TTL以前の回路のことかと思います。
構造
骨格はマージソートと同じで、短いソート済み列を繋げて伸ばしていきます。ただし、マージを行うのに、先頭から1つずつ選択していく教科書の方法では、計算回数が少なくても並列性がなく、スループットが出ません。今回のコードはPE内のみですが、MN-Coreはその高い計算能力に比べて間接参照能力が貧弱なので、多少効率が悪くても多数の命令を発行したほうが早く終わります。具体的には、ちょうどいい位置の値を比較して、必要ならスワップする、ということを繰り返していると、なぜか要素がソートされます。これがSorting Networkです。各比較とスワップは、決まったアドレスの値を参照するだけなので、間接参照を必要としません。
「いい位置」とはなんなのか、言葉で説明するよりも図を見てもらったほうが早いと思います。便利なサイトがあったので、借ります。6を入力して実行すると、今回求めたいグラフが得られます。
左側に64個の入力が並んでおり、右側に向けてあみだくじの要領で進みます。この際、縦の辺が分岐していたら、あみだくじのように問答無用で渡るのではなく、その辺の上下の頂点にそれぞれ左側から来た値を比較スワップし、さらに右に流していきます。
このサイトに6でなくてもっと小さい値を入れると、小問題に対するグラフを出してくれます。64要素のグラフも、左側に1→2→4→8→16とマージする小問題があるのがわかるでしょう。
スワップ
スループットをあげるため、比較は1回で済むなら1回で済ませたいです。以下のコードで、$ls0vと$lr8vの間で、実質的に1行に4回の比較スワップを行えます。
dmax $ls0v $lr8v $lr8v $omr1; l1bmd+0 $lr8v $lbi
l1bmd $lbi $ls0v/$imr1
$lr8vに両者のうち大きい値が書き込まれますが、$lr8vが選ばれた場合、何もしないでそのままにしておきます。$ls0vの値が選ばれるときは、スワップをしなくてはいけないので、マスクを利用して条件付き書き込みを行っています。
レジスタ
この方式で問題となることの一つは、1サイクルの中で同一レジスタの違うアドレスから値を読み出すことはできないため、レジスタに対する値の配置をうまく調整する必要があることです。今回は叩き台なので、紙にグラフを描いてフィーリングでやりました。数式で表せないとスケールしないので、今後の課題です。
コード
dpassa $llm0v $llr0v
dpassa $llm16v $llr16v
dpassa $llm32v $llr32v
dpassa $llm48v $llr48v
dpassa $llm64v $lls0v
dpassa $llm80v $lls16v
dpassa $llm96v $lls32v
dpassa $llm112v $lls48v
dmax $ls[0,6,10,12] $lr[0,6,10,12] $lr[0,6,10,12] $omr1; l1bmd+0 $lr[0,6,10,12] $lbi
dmin $ls[2,4,8,14] $lr[2,4,8,14] $lr[2,4,8,14] $omr2; l1bmd+0 $lr[2,4,8,14] $lbi; l1bmd $lbi $ls[0,6,10,12]/$imr1
dmin $ls[16,22,26,28] $lr[16,22,26,28] $lr[16,22,26,28] $omr1; l1bmd+0 $lr[16,22,26,28] $lbi; l1bmd $lbi $ls[2,4,8,14]/$imr2
dmax $ls[18,20,24,30] $lr[18,20,24,30] $lr[18,20,24,30] $omr2; l1bmd+0 $lr[18,20,24,30] $lbi; l1bmd $lbi $ls[16,22,26,28]/$imr1
dmin $ls[32,38,42,44] $lr[32,38,42,44] $lr[32,38,42,44] $omr1; l1bmd+0 $lr[32,38,42,44] $lbi; l1bmd $lbi $ls[18,20,24,30]/$imr2
dmax $ls[34,36,40,46] $lr[34,36,40,46] $lr[34,36,40,46] $omr2; l1bmd+0 $lr[34,36,40,46] $lbi; l1bmd $lbi $ls[32,38,42,44]/$imr1
dmax $ls[48,54,58,60] $lr[48,54,58,60] $lr[48,54,58,60] $omr1; l1bmd+0 $lr[48,54,58,60] $lbi; l1bmd $lbi $ls[34,36,40,46]/$imr2
dmin $ls[50,52,56,62] $lr[50,52,56,62] $lr[50,52,56,62] $omr2; l1bmd+0 $lr[50,52,56,62] $lbi; l1bmd $lbi $ls[48,54,58,60]/$imr1
dmin $ls[4,6,8,10] $lr[6,4,10,8] $lr[6,4,10,8] $omr1; l1bmd+0 $lr[6,4,10,8] $lbi; l1bmd $lbi $ls[50,52,56,62]/$imr2
dmax $ls[2,0,14,12] $lr[0,2,12,14] $lr[0,2,12,14] $omr2; l1bmd+0 $lr[0,2,12,14] $lbi; l1bmd $lbi $ls[4,6,8,10]/$imr1
dmax $ls[22,20,26,24] $lr[20,22,24,26] $lr[20,22,24,26] $omr1; l1bmd+0 $lr[20,22,24,26] $lbi; l1bmd $lbi $ls[2,0,14,12]/$imr2
dmin $ls[16,18,28,30] $lr[18,16,30,28] $lr[18,16,30,28] $omr2; l1bmd+0 $lr[18,16,30,28] $lbi; l1bmd $lbi $ls[22,20,26,24]/$imr1
dmax $ls[38,36,42,40] $lr[36,38,40,42] $lr[36,38,40,42] $omr1; l1bmd+0 $lr[36,38,40,42] $lbi; l1bmd $lbi $ls[16,18,28,30]/$imr2
dmin $ls[32,34,44,46] $lr[34,32,46,44] $lr[34,32,46,44] $omr2; l1bmd+0 $lr[34,32,46,44] $lbi; l1bmd $lbi $ls[38,36,42,40]/$imr1
dmin $ls[52,54,56,58] $lr[54,52,58,56] $lr[54,52,58,56] $omr1; l1bmd+0 $lr[54,52,58,56] $lbi; l1bmd $lbi $ls[32,34,44,46]/$imr2
dmax $ls[50,48,62,60] $lr[48,50,60,62] $lr[48,50,60,62] $omr2; l1bmd+0 $lr[48,50,60,62] $lbi; l1bmd $lbi $ls[52,54,56,58]/$imr1
dmin $ls[2,14,22,26] $lr[2,14,22,26] $lr[2,14,22,26] $omr1; l1bmd+0 $lr[2,14,22,26] $lbi; l1bmd $lbi $ls[50,48,62,60]/$imr2
dmax $ls[6,10,18,30] $lr[6,10,18,30] $lr[6,10,18,30] $omr2; l1bmd+0 $lr[6,10,18,30] $lbi; l1bmd $lbi $ls[2,14,22,26]/$imr1
dmax $ls[34,46,54,58] $lr[34,46,54,58] $lr[34,46,54,58] $omr1; l1bmd+0 $lr[34,46,54,58] $lbi; l1bmd $lbi $ls[6,10,18,30]/$imr2
dmin $ls[38,42,50,62] $lr[38,42,50,62] $lr[38,42,50,62] $omr2; l1bmd+0 $lr[38,42,50,62] $lbi; l1bmd $lbi $ls[34,46,54,58]/$imr1
dmax $ls[4,2,6,0] $lr[0,6,2,4] $lr[0,6,2,4] $omr1; l1bmd+0 $lr[0,6,2,4] $lbi; l1bmd $lbi $ls[38,42,50,62]/$imr2
dmin $ls[8,14,10,12] $lr[12,10,14,8] $lr[12,10,14,8] $omr2; l1bmd+0 $lr[12,10,14,8] $lbi; l1bmd $lbi $ls[4,2,6,0]/$imr1
dmin $ls[16,22,18,20] $lr[20,18,22,16] $lr[20,18,22,16] $omr1; l1bmd+0 $lr[20,18,22,16] $lbi; l1bmd $lbi $ls[8,14,10,12]/$imr2
dmax $ls[28,26,30,24] $lr[24,30,26,28] $lr[24,30,26,28] $omr2; l1bmd+0 $lr[24,30,26,28] $lbi; l1bmd $lbi $ls[16,22,18,20]/$imr1
dmin $ls[32,38,34,36] $lr[36,34,38,32] $lr[36,34,38,32] $omr1; l1bmd+0 $lr[36,34,38,32] $lbi; l1bmd $lbi $ls[28,26,30,24]/$imr2
dmax $ls[44,42,46,40] $lr[40,46,42,44] $lr[40,46,42,44] $omr2; l1bmd+0 $lr[40,46,42,44] $lbi; l1bmd $lbi $ls[32,38,34,36]/$imr1
dmax $ls[52,50,54,48] $lr[48,54,50,52] $lr[48,54,50,52] $omr1; l1bmd+0 $lr[48,54,50,52] $lbi; l1bmd $lbi $ls[44,42,46,40]/$imr2
dmin $ls[56,62,58,60] $lr[60,58,62,56] $lr[60,58,62,56] $omr2; l1bmd+0 $lr[60,58,62,56] $lbi; l1bmd $lbi $ls[52,50,54,48]/$imr1
dmax $ls[10,12,18,20] $lr[12,10,20,18] $lr[12,10,20,18] $omr1; l1bmd+0 $lr[12,10,20,18] $lbi; l1bmd $lbi $ls[56,62,58,60]/$imr2
dmin $ls[4,2,28,26] $lr[2,4,26,28] $lr[2,4,26,28] $omr2; l1bmd+0 $lr[2,4,26,28] $lbi; l1bmd $lbi $ls[10,12,18,20]/$imr1
dmin $ls[44,42,52,50] $lr[42,44,50,52] $lr[42,44,50,52] $omr1; l1bmd+0 $lr[42,44,50,52] $lbi; l1bmd $lbi $ls[4,2,28,26]/$imr2
dmax $ls[34,36,58,60] $lr[36,34,60,58] $lr[36,34,60,58] $omr2; l1bmd+0 $lr[36,34,60,58] $lbi; l1bmd $lbi $ls[44,42,52,50]/$imr1
dmax $ls[14,10,12,22] $lr[12,10,14,20] $lr[12,10,14,20] $omr1; l1bmd+0 $lr[12,10,14,20] $lbi; l1bmd $lbi $ls[34,36,58,60]/$imr2
dmin $ls[4,2,6,28] $lr[6,2,4,30] $lr[6,2,4,30] $omr2; l1bmd+0 $lr[6,2,4,30] $lbi; l1bmd $lbi $ls[14,10,12,22]/$imr1
dmax $ls[18,20,38,34] $lr[18,22,36,34] $lr[18,22,36,34] $omr1; l1bmd+0 $lr[18,22,36,34] $lbi; l1bmd $lbi $ls[4,2,6,28]/$imr2
dmin $ls[26,30,44,42] $lr[26,28,46,42] $lr[26,28,46,42] $omr2; l1bmd+0 $lr[26,28,46,42] $lbi; l1bmd $lbi $ls[18,20,38,34]/$imr1
dmin $ls[46,52,50,54] $lr[44,54,50,52] $lr[44,54,50,52] $omr1; l1bmd+0 $lr[44,54,50,52] $lbi; l1bmd $lbi $ls[26,30,44,42]/$imr2
dmax $ls[36,62,58,60] $lr[38,60,58,62] $lr[38,60,58,62] $omr2; l1bmd+0 $lr[38,60,58,62] $lbi; l1bmd $lbi $ls[46,52,50,54]/$imr1
dmax $ls[8,4,14,2] $lr[0,12,6,10] $lr[0,12,6,10] $omr1; l1bmd+0 $lr[0,12,6,10] $lbi; l1bmd $lbi $ls[36,62,58,60]/$imr2
dmax $ls[10,6,12,0] $lr[2,14,4,8] $lr[2,14,4,8] $omr2; l1bmd+0 $lr[2,14,4,8] $lbi; l1bmd $lbi $ls[8,4,14,2]/$imr1
dmin $ls[16,28,22,26] $lr[24,20,30,18] $lr[24,20,30,18] $omr1; l1bmd+0 $lr[24,20,30,18] $lbi; l1bmd $lbi $ls[10,6,12,0]/$imr2
dmin $ls[18,30,20,24] $lr[26,22,28,16] $lr[26,22,28,16] $omr2; l1bmd+0 $lr[26,22,28,16] $lbi; l1bmd $lbi $ls[16,28,22,26]/$imr1
dmin $ls[32,44,38,42] $lr[40,36,46,34] $lr[40,36,46,34] $omr1; l1bmd+0 $lr[40,36,46,34] $lbi; l1bmd $lbi $ls[18,30,20,24]/$imr2
dmin $ls[34,46,36,40] $lr[42,38,44,32] $lr[42,38,44,32] $omr2; l1bmd+0 $lr[42,38,44,32] $lbi; l1bmd $lbi $ls[32,44,38,42]/$imr1
dmax $ls[56,52,62,50] $lr[48,60,54,58] $lr[48,60,54,58] $omr1; l1bmd+0 $lr[48,60,54,58] $lbi; l1bmd $lbi $ls[34,46,36,40]/$imr2
dmax $ls[58,54,60,48] $lr[50,62,52,56] $lr[50,62,52,56] $omr2; l1bmd+0 $lr[50,62,52,56] $lbi; l1bmd $lbi $ls[56,52,62,50]/$imr1
dmin $ls[8,4,14,2] $lr[2,14,4,8] $lr[2,14,4,8] $omr1; l1bmd+0 $lr[2,14,4,8] $lbi; l1bmd $lbi $ls[58,54,60,48]/$imr2
dmax $ls[18,30,20,24] $lr[24,20,30,18] $lr[24,20,30,18] $omr2; l1bmd+0 $lr[24,20,30,18] $lbi; l1bmd $lbi $ls[8,4,14,2]/$imr1
dmax $ls[34,46,36,40] $lr[40,36,46,34] $lr[40,36,46,34] $omr1; l1bmd+0 $lr[40,36,46,34] $lbi; l1bmd $lbi $ls[18,30,20,24]/$imr2
dmin $ls[56,52,62,50] $lr[50,62,52,56] $lr[50,62,52,56] $omr2; l1bmd+0 $lr[50,62,52,56] $lbi; l1bmd $lbi $ls[34,46,36,40]/$imr1
dmin $ls[8,4,14,2] $lr[6,10,2,14] $lr[6,10,2,14] $omr1; l1bmd+0 $lr[6,10,2,14] $lbi; l1bmd $lbi $ls[56,52,62,50]/$imr2
dmax $ls[22,26,18,30] $lr[24,20,30,18] $lr[24,20,30,18] $omr2; l1bmd+0 $lr[24,20,30,18] $lbi; l1bmd $lbi $ls[8,4,14,2]/$imr1
dmax $ls[20,24,38,42] $lr[26,22,40,36] $lr[26,22,40,36] $omr1; l1bmd+0 $lr[26,22,40,36] $lbi; l1bmd $lbi $ls[22,26,18,30]/$imr2
dmax $ls[34,46,36,40] $lr[46,34,42,38] $lr[46,34,42,38] $omr2; l1bmd+0 $lr[46,34,42,38] $lbi; l1bmd $lbi $ls[20,24,38,42]/$imr1
dmin $ls[10,6,56,52] $lr[4,8,54,58] $lr[4,8,54,58] $omr1; l1bmd+0 $lr[4,8,54,58] $lbi; l1bmd $lbi $ls[34,46,36,40]/$imr2
dmin $ls[62,50,58,54] $lr[50,62,52,56] $lr[50,62,52,56] $omr2; l1bmd+0 $lr[50,62,52,56] $lbi; l1bmd $lbi $ls[10,6,56,52]/$imr1
dmin $ls[8,4,14,2] $lr[12,6,10,2] $lr[12,6,10,2] $omr1; l1bmd+0 $lr[12,6,10,2] $lbi; l1bmd $lbi $ls[62,50,58,54]/$imr2
dmax $ls[28,22,26,18] $lr[24,20,30,18] $lr[24,20,30,18] $omr2; l1bmd+0 $lr[24,20,30,18] $lbi; l1bmd $lbi $ls[8,4,14,2]/$imr1
dmax $ls[30,20,24,44] $lr[26,22,28,40] $lr[26,22,28,40] $omr1; l1bmd+0 $lr[26,22,28,40] $lbi; l1bmd $lbi $ls[28,22,26,18]/$imr2
dmax $ls[38,42,34,46] $lr[36,46,34,42] $lr[36,46,34,42] $omr2; l1bmd+0 $lr[36,46,34,42] $lbi; l1bmd $lbi $ls[30,20,24,44]/$imr1
dmin $ls[10,6,12,56] $lr[14,4,8,60] $lr[14,4,8,60] $omr1; l1bmd+0 $lr[14,4,8,60] $lbi; l1bmd $lbi $ls[38,42,34,46]/$imr2
dmin $ls[52,62,50,58] $lr[54,58,50,62] $lr[54,58,50,62] $omr2; l1bmd+0 $lr[54,58,50,62] $lbi; l1bmd $lbi $ls[10,6,12,56]/$imr1
dmax $ls[36,40,16,8] $lr[38,44,0,24] $lr[38,44,0,24] $omr1; l1bmd+0 $lr[38,44,0,24] $lbi; l1bmd $lbi $ls[52,62,50,58]/$imr2
dmax $ls[28,4,22,14] $lr[12,20,6,30] $lr[12,20,6,30] $omr2; l1bmd+0 $lr[12,20,6,30] $lbi; l1bmd $lbi $ls[36,40,16,8]/$imr1
dmax $ls[26,2,18,10] $lr[10,18,2,26] $lr[10,18,2,26] $omr1; l1bmd+0 $lr[10,18,2,26] $lbi; l1bmd $lbi $ls[28,4,22,14]/$imr2
dmax $ls[30,6,20,12] $lr[14,22,4,28] $lr[14,22,4,28] $omr2; l1bmd+0 $lr[14,22,4,28] $lbi; l1bmd $lbi $ls[26,2,18,10]/$imr1
dmin $ls[54,60,32,56] $lr[52,56,48,40] $lr[52,56,48,40] $omr1; l1bmd+0 $lr[52,56,48,40] $lbi; l1bmd $lbi $ls[30,6,20,12]/$imr2
dmin $ls[44,52,38,62] $lr[60,36,54,46] $lr[60,36,54,46] $omr2; l1bmd+0 $lr[60,36,54,46] $lbi; l1bmd $lbi $ls[54,60,32,56]/$imr1
dmin $ls[42,50,34,58] $lr[58,34,50,42] $lr[58,34,50,42] $omr1; l1bmd+0 $lr[58,34,50,42] $lbi; l1bmd $lbi $ls[44,52,38,62]/$imr2
dmin $ls[46,54,36,60] $lr[62,38,52,44] $lr[62,38,52,44] $omr2; l1bmd+0 $lr[62,38,52,44] $lbi; l1bmd $lbi $ls[42,50,34,58]/$imr1
dmin $ls[40,48,16,8] $lr[56,32,2,26] $lr[56,32,2,26] $omr1; l1bmd+0 $lr[56,32,2,26] $lbi; l1bmd $lbi $ls[46,54,36,60]/$imr2
dmin $ls[28,4,22,14] $lr[14,22,4,28] $lr[14,22,4,28] $omr2; l1bmd+0 $lr[14,22,4,28] $lbi; l1bmd $lbi $ls[40,48,16,8]/$imr1
dmax $ls[24,0,34,58] $lr[8,16,48,40] $lr[8,16,48,40] $omr1; l1bmd+0 $lr[8,16,48,40] $lbi; l1bmd $lbi $ls[28,4,22,14]/$imr2
dmax $ls[46,54,36,60] $lr[60,36,54,46] $lr[60,36,54,46] $omr2; l1bmd+0 $lr[60,36,54,46] $lbi; l1bmd $lbi $ls[24,0,34,58]/$imr1
dmin $ls[26,2,16,8] $lr[8,16,6,30] $lr[8,16,6,30] $omr1; l1bmd+0 $lr[8,16,6,30] $lbi; l1bmd $lbi $ls[46,54,36,60]/$imr2
dmin $ls[28,4,22,14] $lr[10,18,2,26] $lr[10,18,2,26] $omr2; l1bmd+0 $lr[10,18,2,26] $lbi; l1bmd $lbi $ls[26,2,16,8]/$imr1
dmax $ls[40,48,38,62] $lr[58,34,48,40] $lr[58,34,48,40] $omr4; l1bmd+0 $lr[58,34,48,40] $lbi; l1bmd $lbi $ls[28,4,22,14]/$imr2
dmin $ls[26,2,18,10] $lr[14,22,4,28] $lr[14,22,4,28] $omr3; l1bmd+0 $lr[14,22,4,28] $lbi; l1bmd $lbi $ls[40,48,38,62]/$imr4
dmax $ls[42,50,34,58] $lr[60,36,54,46] $lr[60,36,54,46] $omr1; l1bmd+0 $lr[60,36,54,46] $lbi; l1bmd $lbi $ls[26,2,18,10]/$imr3
dmax $ls[46,54,36,60] $lr[58,34,50,42] $lr[58,34,50,42] $omr2; l1bmd+0 $lr[58,34,50,42] $lbi; l1bmd $lbi $ls[42,50,34,58]/$imr1
dmin $ls[30,6,16,8] $lr[8,16,12,20] $lr[8,16,12,20] $omr1; l1bmd+0 $lr[8,16,12,20] $lbi; l1bmd $lbi $ls[46,54,36,60]/$imr2
dmin $ls[28,4,22,14] $lr[6,30,10,18] $lr[6,30,10,18] $omr2; l1bmd+0 $lr[6,30,10,18] $lbi; l1bmd $lbi $ls[30,6,16,8]/$imr1
dmin $ls[26,2,18,10] $lr[2,26,14,22] $lr[2,26,14,22] $omr1; l1bmd+0 $lr[2,26,14,22] $lbi; l1bmd $lbi $ls[28,4,22,14]/$imr2
dmin $ls[30,6,20,12] $lr[4,28,8,16] $lr[4,28,8,16] $omr2; l1bmd+0 $lr[4,28,8,16] $lbi; l1bmd $lbi $ls[26,2,18,10]/$imr1
dmax $ls[40,48,44,52] $lr[62,38,48,40] $lr[62,38,48,40] $omr1; l1bmd+0 $lr[62,38,48,40] $lbi; l1bmd $lbi $ls[30,6,20,12]/$imr2
dmax $ls[38,62,42,50] $lr[60,36,54,46] $lr[60,36,54,46] $omr2; l1bmd+0 $lr[60,36,54,46] $lbi; l1bmd $lbi $ls[40,48,44,52]/$imr1
dmax $ls[34,58,46,54] $lr[58,34,50,42] $lr[58,34,50,42] $omr1; l1bmd+0 $lr[58,34,50,42] $lbi; l1bmd $lbi $ls[38,62,42,50]/$imr2
dmax $ls[36,60,40,48] $lr[62,38,52,44] $lr[62,38,52,44] $omr2; l1bmd+0 $lr[62,38,52,44] $lbi; l1bmd $lbi $ls[34,58,46,54]/$imr1
dmin $ls[16,8,28,4] $lr[24,12,20,6] $lr[24,12,20,6] $omr1; l1bmd+0 $lr[24,12,20,6] $lbi; l1bmd $lbi $ls[36,60,40,48]/$imr2
dmin $ls[22,14,26,2] $lr[30,10,18,2] $lr[30,10,18,2] $omr2; l1bmd+0 $lr[30,10,18,2] $lbi; l1bmd $lbi $ls[16,8,28,4]/$imr1
dmin $ls[18,10,30,6] $lr[26,14,22,4] $lr[26,14,22,4] $omr1; l1bmd+0 $lr[26,14,22,4] $lbi; l1bmd $lbi $ls[22,14,26,2]/$imr2
dmin $ls[20,12,24,24] $lr[28,8,16,16] $lr[28,8,16,16] $omr3; l1bmd+0 $lr[28,8,16,16] $lbi; l1bmd $lbi $ls[18,10,30,6]/$imr1
dmax $ls[56,44,52,38] $lr[48,40,60,36] $lr[48,40,60,36] $omr2; l1bmd+0 $lr[48,40,60,36] $lbi; l1bmd $lbi $ls[20,12,24,24]/$imr3
dmax $ls[62,42,50,34] $lr[54,46,58,34] $lr[54,46,58,34] $omr1; l1bmd+0 $lr[54,46,58,34] $lbi; l1bmd $lbi $ls[56,44,52,38]/$imr2
dmax $ls[58,46,54,36] $lr[50,42,62,38] $lr[50,42,62,38] $omr2; l1bmd+0 $lr[50,42,62,38] $lbi; l1bmd $lbi $ls[62,42,50,34]/$imr1
dmax $ls[60,40,48,32] $lr[52,44,56,0] $lr[52,44,56,0] $ln[0,0,0,0] $omr1; l1bmd+0 $lr[52,44,56,0] $lbi; l1bmd $lbi $ls[58,46,54,36]/$imr2
dmax $ls[16,56,8,44] $lr[48,24,40,12] $lr[48,24,40,12] $omr2; l1bmd+0 $lr[48,24,40,12] $lbi; l1bmd $lbi $ls[60,40,48,32]/$imr1
dmax $ls[28,52,4,38] $lr[60,20,36,6] $lr[60,20,36,6] $omr1; l1bmd+0 $lr[60,20,36,6] $lbi; l1bmd $lbi $ls[16,56,8,44]/$imr2
dmax $ls[22,62,14,42] $lr[54,30,46,10] $lr[54,30,46,10] $omr2; l1bmd+0 $lr[54,30,46,10] $lbi; l1bmd $lbi $ls[28,52,4,38]/$imr1
dmax $ls[26,50,2,34] $lr[58,18,34,2] $lr[58,18,34,2] $omr1; l1bmd+0 $lr[58,18,34,2] $lbi; l1bmd $lbi $ls[22,62,14,42]/$imr2
dmax $ls[18,58,10,46] $lr[50,26,42,14] $lr[50,26,42,14] $omr2; l1bmd+0 $lr[50,26,42,14] $lbi; l1bmd $lbi $ls[26,50,2,34]/$imr1
dmax $ls[30,54,6,36] $lr[62,22,38,4] $lr[62,22,38,4] $omr1; l1bmd+0 $lr[62,22,38,4] $lbi; l1bmd $lbi $ls[18,58,10,46]/$imr2
dmax $ls[20,60,12,40] $lr[52,28,44,8] $lr[52,28,44,8] $omr2; l1bmd+0 $lr[52,28,44,8] $lbi; l1bmd $lbi $ls[30,54,6,36]/$imr1
dmax $ls[24,48,0,0] $lr[56,16,32,32] $lr[56,16,32,32] $omr3; l1bmd+0 $lr[56,16,32,32] $lbi; l1bmd $lbi $ls[20,60,12,40]/$imr2
dmin $ls[32,16,56,8] $lr[2,50,26,42] $lr[2,50,26,42] $omr1; l1bmd+0 $lr[2,50,26,42] $lbi; l1bmd $lbi $ls[24,48,0,0]/$imr3
dmin $ls[44,28,52,4] $lr[14,62,22,38] $lr[14,62,22,38] $omr2; l1bmd+0 $lr[14,62,22,38] $lbi; l1bmd $lbi $ls[32,16,56,8]/$imr1
dmin $ls[38,22,62,14] $lr[4,52,28,44] $lr[4,52,28,44] $omr1; l1bmd+0 $lr[4,52,28,44] $lbi; l1bmd $lbi $ls[44,28,52,4]/$imr2
dmin $ls[42,26,50,2] $lr[8,56,16,32] $lr[8,56,16,32] $omr2; l1bmd+0 $lr[8,56,16,32] $lbi; l1bmd $lbi $ls[38,22,62,14]/$imr1
dmin $ls[32,16,56,8] $lr[6,54,30,46] $lr[6,54,30,46] $omr1; l1bmd+0 $lr[6,54,30,46] $lbi; l1bmd $lbi $ls[42,26,50,2]/$imr2
dmin $ls[44,28,52,4] $lr[10,58,18,34] $lr[10,58,18,34] $omr2; l1bmd+0 $lr[10,58,18,34] $lbi; l1bmd $lbi $ls[32,16,56,8]/$imr1
dmin $ls[38,22,62,14] $lr[2,50,26,42] $lr[2,50,26,42] $omr1; l1bmd+0 $lr[2,50,26,42] $lbi; l1bmd $lbi $ls[44,28,52,4]/$imr2
dmin $ls[42,26,50,2] $lr[14,62,22,38] $lr[14,62,22,38] $omr2; l1bmd+0 $lr[14,62,22,38] $lbi; l1bmd $lbi $ls[38,22,62,14]/$imr1
dmin $ls[34,18,58,10] $lr[4,52,28,44] $lr[4,52,28,44] $omr1; l1bmd+0 $lr[4,52,28,44] $lbi; l1bmd $lbi $ls[42,26,50,2]/$imr2
dmin $ls[46,30,54,6] $lr[8,56,16,32] $lr[8,56,16,32] $omr2; l1bmd+0 $lr[8,56,16,32] $lbi; l1bmd $lbi $ls[34,18,58,10]/$imr1
dmin $ls[32,16,56,8] $lr[12,60,20,36] $lr[12,60,20,36] $omr1; l1bmd+0 $lr[12,60,20,36] $lbi; l1bmd $lbi $ls[46,30,54,6]/$imr2
dmin $ls[44,28,52,4] $lr[6,54,30,46] $lr[6,54,30,46] $omr2; l1bmd+0 $lr[6,54,30,46] $lbi; l1bmd $lbi $ls[32,16,56,8]/$imr1
dmin $ls[38,22,62,14] $lr[10,58,18,34] $lr[10,58,18,34] $omr1; l1bmd+0 $lr[10,58,18,34] $lbi; l1bmd $lbi $ls[44,28,52,4]/$imr2
dmin $ls[42,26,50,2] $lr[2,50,26,42] $lr[2,50,26,42] $omr2; l1bmd+0 $lr[2,50,26,42] $lbi; l1bmd $lbi $ls[38,22,62,14]/$imr1
dmin $ls[34,18,58,10] $lr[14,62,22,38] $lr[14,62,22,38] $omr1; l1bmd+0 $lr[14,62,22,38] $lbi; l1bmd $lbi $ls[42,26,50,2]/$imr2
dmin $ls[46,30,54,6] $lr[4,52,28,44] $lr[4,52,28,44] $omr2; l1bmd+0 $lr[4,52,28,44] $lbi; l1bmd $lbi $ls[34,18,58,10]/$imr1
dmin $ls[36,20,60,12] $lr[8,56,16,32] $lr[8,56,16,32] $omr1; l1bmd+0 $lr[8,56,16,32] $lbi; l1bmd $lbi $ls[46,30,54,6]/$imr2
dmin $ls[32,16,56,8] $lr[24,40,12,60] $lr[24,40,12,60] $omr2; l1bmd+0 $lr[24,40,12,60] $lbi; l1bmd $lbi $ls[36,20,60,12]/$imr1
dmin $ls[44,28,52,4] $lr[20,36,6,54] $lr[20,36,6,54] $omr1; l1bmd+0 $lr[20,36,6,54] $lbi; l1bmd $lbi $ls[32,16,56,8]/$imr2
dmin $ls[38,22,62,14] $lr[30,46,10,58] $lr[30,46,10,58] $omr2; l1bmd+0 $lr[30,46,10,58] $lbi; l1bmd $lbi $ls[44,28,52,4]/$imr1
dmin $ls[42,26,50,2] $lr[18,34,2,50] $lr[18,34,2,50] $omr1; l1bmd+0 $lr[18,34,2,50] $lbi; l1bmd $lbi $ls[38,22,62,14]/$imr2
dmin $ls[34,18,58,10] $lr[26,42,14,62] $lr[26,42,14,62] $omr2; l1bmd+0 $lr[26,42,14,62] $lbi; l1bmd $lbi $ls[42,26,50,2]/$imr1
dmin $ls[46,30,54,6] $lr[22,38,4,52] $lr[22,38,4,52] $omr1; l1bmd+0 $lr[22,38,4,52] $lbi; l1bmd $lbi $ls[34,18,58,10]/$imr2
dmin $ls[36,20,60,12] $lr[28,44,8,56] $lr[28,44,8,56] $omr2; l1bmd+0 $lr[28,44,8,56] $lbi; l1bmd $lbi $ls[46,30,54,6]/$imr1
dmin $ls[40,24,32,16] $lr[16,32,48,24] $lr[16,32,48,24] $ln[4,4,4,8] $omr1; l1bmd+0 $lr[16,32,48,24] $lbi; l1bmd $lbi $ls[36,20,60,12]/$imr2
dmin $ls[56,8,44,28] $lr[40,12,60,20] $lr[40,12,60,20] $ln12v4 $omr2; l1bmd+0 $lr[40,12,60,20] $lbi; l1bmd $lbi $ls[40,24,32,16]/$imr1
dmin $ls[52,4,38,22] $lr[36,6,54,30] $lr[36,6,54,30] $ln28v4 $omr1; l1bmd+0 $lr[36,6,54,30] $lbi; l1bmd $lbi $ls[56,8,44,28]/$imr2
dmin $ls[62,14,42,26] $lr[46,10,58,18] $lr[46,10,58,18] $ln44v4 $omr2; l1bmd+0 $lr[46,10,58,18] $lbi; l1bmd $lbi $ls[52,4,38,22]/$imr1
dmin $ls[50,2,34,18] $lr[34,2,50,26] $lr[34,2,50,26] $ln60v4 $omr1; l1bmd+0 $lr[34,2,50,26] $lbi; l1bmd $lbi $ls[62,14,42,26]/$imr2
dmin $ls[58,10,46,30] $lr[42,14,62,22] $lr[42,14,62,22] $ln76v4 $omr2; l1bmd+0 $lr[42,14,62,22] $lbi; l1bmd $lbi $ls[50,2,34,18]/$imr1
dmin $ls[54,6,36,20] $lr[38,4,52,28] $lr[38,4,52,28] $ln92v4 $omr1; l1bmd+0 $lr[38,4,52,28] $lbi; l1bmd $lbi $ls[58,10,46,30]/$imr2
dmin $ls[60,12,40,24] $lr[44,8,56,16] $lr[44,8,56,16] $ln108v4 $omr2; l1bmd+0 $lr[44,8,56,16] $lbi; l1bmd $lbi $ls[54,6,36,20]/$imr1
dmin $ls48 $lr32 $lr32 $ln124 $omr3; l1bmd+0 $lr32 $lbi; l1bmd $lbi $ls[60,12,40,24]/$imr2
dpassa $ls[32,16,56,8] $ln[2,6,10,14]; l1bmd $lbi $ls48/$imr3
dpassa $ls[44,28,52,4] $ln[18,22,26,30]
dpassa $ls[38,22,62,14] $ln[34,38,42,46]
dpassa $ls[42,26,50,2] $ln[50,54,58,62]
dpassa $ls[34,18,58,10] $ln[66,70,74,78]
dpassa $ls[46,30,54,6] $ln[82,86,90,94]
dpassa $ls[36,20,60,12] $ln[98,102,106,110]
dpassa $ls[40,24,48,0] $ln[114,118,122,126]
展望
前後の転送命令を無視すれば、比較の数(543回)から導かれる行数の限界、146行にあと1行というところまで近づけました。いったんこの問題はここでやめて、この問題をMAB間方向のPE16個に渡る1024要素のソートへと改題したものを解いてみようと思っています。Sorting Networkをそのまま使うと効率が悪く、問題を分割することでコードを削ることができます。できたらまた記事を書きます。