ToDo:
LP64環境での中期的な運用維持のため、整理実施
現行実装では、*list配列と*stk配列のアドレス空間共有を前提としているコードが残っていることから、一部制限あり
将来的には、下記の依存コードの再実装後の*stk配列空間のアドレス分離により解消予定
個別に実装されているsort algorithmをlibc等の実装に置き換える
quick sortに関しては、qsort_sを採用したが、ISO C11のExtension1なので未実装の環境が多いのが難点
関連するコードの検証・再実装を進めているうちにいくつかバグを発見
次に作るもの
性能に関しては、オリジナル実装では実数リスト等のケースで比較ルーチンがソートエンジン内に展開されているのに対して、qsort(3)等では関数呼び出しが必須となる点は不利だが、実数リストコンテナではインデックスソートではなく、出力配列を直接スワップすることで間接参照コストを低減する最適化を行ったため、N = 2^24でのテストでは、整列・逆整列・準整列・ランダムの各パターンで、オリジナル実装よりも概ね良好な性能が得られている
ISO C++がテンプレート版sortがつかえれば、比較ルーチンのinline展開により更なる改善が得られると思われる
list containerにする前の編集可能なsequence container utilityの設計案をまとめておく
長さに関しては、list containerが 2^31-1で制限されているので、 size_tでは無くintで充分(念のためにunsignedで定義すべき)
更新系の動作に関しては、
のバリエーションが考えられる
編集結果をlist containerやsequenceで返す場合、生成型の動作がメモリ割り当て効率的に望ましいが、命名規則を考える必要がある
sort engine入れ替え後にregressionしたので調査したが、リストをスタック上に展開して舐める際に、空のリストが考慮されていないのが、原因だった
オリジナルコードだと、直前にUnion1をスタック経由で呼び出す際の引数がスタック上に存在するので、無効参照を避けているが、演算結果は結果が正しくない
問題を起こすのは、第二引数が空のリストのケース
Intersection[{3,1,{},2}, {}]
空集合との積集合なので{}を返すべきところを{{}}を返す
Complement[{3,1,{},2}, {}]
空集合を除外するので、{1,2,3,{}}を返すべきところを{1,2,3}を返す
さらに、戻り値の構築をitflistで行うため、スタックが空(空集合)のケースでは、itflistからitfcrelistmへ頭部(ntfoper, mtfleftbrace)で移譲され、itfcrelistmが構築済みのiaxnulll空リストコンテナの参照を返すが、その後にcopyheadで頭部を挿入する過程で、構築済み空リストが汚染されている
標準化という意味での本命は、ISO C11 Annex.Kのqsort_s(3)だけど実装している環境はFreeBSDやMicrosoftぐらいか?
glibcのqsort_rは戻り値が無い以外は、ほぼqsort_s
次点は、ISO C++にlabmdaで標準化された無形クロージャに対応する機能がISO Cで標準化されることとだが…どうなんでしょう?
実装例的には、LLVM/clangのBlock構文拡張がそのものズバリなのだが…
GCCのNested Function拡張も近いけど、あくまでもローカルスコープ上で定義・参照可能な関数なので、リテラルで引数に積めない、クロージャとして戻り値に出来ないあたりがlambdaやBlock構文拡張に劣る
実用面では、FreeBSDのGitHubからqsort/qsort_sの実装を持ち込む辺りか?
古い教科書には、平均的なケースではオーバーヘッドが多いmergesortはquicksortに勝てない的な言説が書かれているが、現代的なハードウェアでの実測だと比較回数が同程度の状況でmergesortがquicksortに劣る事例は以外と少ない、またその差が小さい模様
初期順序が同一でも比較操作時の間接参照が増えるとquicksortに逆転されることから、キャッシュ階層が深い計算機環境では、mergesortの方がメモリアクセスの連続性が高い(マージ操作)ためにキャッシュ効き易いためではと推測される
ちなみに、heapsortの実行時間は$N\log{N}$で安定だが、quick/mergesortに比べて数倍〜10倍程度遅い模様
$O(N)$の作業領域が安定して確保出来る状況であれば、mergesortを標準にしたほうが良さそうだが、標準実装してるのはBSD系ぐらいで、再入可能なmergesortを標準実装してるのはBlock拡張付きのDarwinとFreeBSDぐらいなのが玉に瑕
LINE["S", position + frac]の動作が、Twiss[*, position + frac]系と異なるバグが昔から知られているが、少し深堀りしてみた
原因は、positionの次のbeamline-elementがOFFSET付きMARKerの場合、beamlineに沿った内部配列の次の要素が物理的に異なる場所を指しているにも関わらず、線形補間するためであるが、自体はもう少しややこしい模様
明らかに線形の変化で無い要素に関しては、qfraccompで一時的にbeamline-elementのパラメータをfracでスケールして部分的に再計算しているため、GEOなどは正しく扱われている模様
現時点で判明している正しくないLINEのkeywordは以下の通り
調査過程で、SIZE*keywordに関しては、itfsize配列の割り当て状況を検査していないので、SEGVで落ちるケースが発見された
Rev.6409時点では、S,LENG,GAMMA,GAMMABETAの補間は修正済み、SIZE*に関しては未割り当て時はエラーを返すように変更済み
カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記