注意 : ちょっと考えれば, 「親」は, 配列を二つに分けることしかしておら ず, 肝腎の整列は「子」に全部任せて待つだけということが分かる. 通信はそ れなりにコストがかかるし, server の立ち上げはとてもコストがかかるので, こんなことをしても効率向上は望めないが, こんなことが簡単に実行できると いう例として紹介している.
#define LevelMax 2 Proc1 = -1$ Proc2 = -1$ def quickSort(A,P,Q,Level) { extern Proc1, Proc2; if (Q-P < 1) return A; print("Level=",0); print(Level); Mp = idiv(P+Q,2); M = A[Mp]; B = P; E = Q; while (1) { while (A[B] < M) B++; while (A[E] > M && B <= E) E--; if (B >= E) break; else { Tmp = A[B]; A[B] = A[E]; A[E] = Tmp; E--; } } if (E < P) E = P; /* -------------------------- */ if (Level < LevelMax) { if (Proc1 == -1) { Proc1 = ox_launch(); } if (Proc2 == -1) { Proc2 = ox_launch(); } ox_rpc(Proc1,"quickSort",A,P,E,Level+1); ox_rpc(Proc2,"quickSort",A,E+1,Q,Level+1); if (E-P < Q-E) { A1 = ox_pop_local(Proc1); A2 = ox_pop_local(Proc2); }else{ A2 = ox_pop_local(Proc2); A1 = ox_pop_local(Proc1); } for (I=P; I<=E; I++) { A[I] = A1[I]; } for (I=E+1; I<=Q; I++) { A[I] = A2[I]; } return(A); /* -------------------------- */ }else{ quickSort(A,P,E,Level+1); quickSort(A,E+1,Q,Level+1); return(A); } } end$このプログラムは第 14 章のものとほとんど同じで, 異なる のは
/* -------------------------- */
ではさまれた部分のみである.
このプログラムでは, ox_launch() により動的に ox_asir を
起動しているので, 起動時にこの関数が定義されるように, .asirrc に
書いておく必要がある. たとえば, この関数が含まれるファイルを
/home/noro/asir/d_qsort とすれば, .asirrc に
load("/home/noro/asir/d_qsort")$を追加しておけばよい. この関数では, 際限なく server が生成されるのを防 ぐために, 再帰の段数が LevelMax という定数を越えたら自プロセス内で再帰 するようにしてある. また, 一旦 server が生成されたらその識別番号を覚えて おき, 無駄に server を生成しないようにもしてある. (いくら効率無視でも このような工夫は必要. 特に段数の制限は重要. さもないと計算機自体がストップ してしまうこともあり得る. )