トップ «前の日(12-08) 最新 次の日(12-10)» 追記

Orz日記 by Akio Morita

ToDo:

  • 15 SAD Fit[]回りの障害事例の解析
  • 10 smart pointer版PEGクラスの再実装(Left Recursionまわり)
2006|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|06|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|07|08|09|10|11|12|
2013|01|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|06|07|08|10|12|
2016|01|02|03|05|06|08|10|11|
2017|01|02|03|04|05|06|07|09|10|11|12|
2018|01|02|03|04|06|07|08|09|10|11|12|
2019|01|03|04|05|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|

2006-12-08

_ [雑記]マシンの仮組み

miniSASケーブルはまだ届かないが、ケースへの仮組み開始

マザーボード実装 マザーボードをH360Cへ実装

CSE-M14T and PX-716A CSE-M14TとPX-716Aをブラケットに仮組み

本体仮組み 本体シャーシーの仮組み

CSE-M14T用に開閉式の蓋を外す

組み上がったケース外観


2017-12-08

_ [SAD][EPICS]ca_create_channelとca_getに対するca_pend_ioに付いて

マニュアルを読んだ範囲では、handler無しのca_create_channelとca_getのrequestの完了を待つ際の ca_pend_ioの戻り値に付いてまとめると

ECA_NORMAL

ca_pend_ioに先行するhandler無しの ca_create_channelとca_get要求全ての処理が完了している

ECA_TIMEOUT

ca_pend_ioに先行するhandler無しの ca_create_channelとca_get要求のなかに、未完了のものが含まれる。

=未完了の要求のうち、ca_get要求は再実行されるがca_create_channel要求は再実行されない=(2017/12/11訂正)

ca_pend_io以前に投入されたhandler無しのca_create_channel/ca_get要求は、終了・キャンセルされている。 ただし、CA APIレベルで状態を持たないca_get要求の成否は不明となる (2017/12/11追記)

ca_create_channelに関しては、ca_pend_ioからECA_TIMEOUTで戻った時点で接続状態が確定し、ca_stateが cs_never_connもしくはca_prev_conn状態となっており、ca_clear_channelするまで変わらない。 また、ca_create_channelで生成したchidオブジェクトをca_stateで調べれば、接続確立に失敗しているchannelを特定できる(未接続で確定しているので、以降のca_get/ca_putがECA_DISCONNで失敗するので、ca_clear_channelで捨てる以外することが無いはず)

=一方、ca_get要求は再投入されるとのことなので、ca_getへ渡したbuffer pointerは、CA client library内で生存しており、ca_pend_ioがECA_NORMALを返すまで開放することが出来ない=(ca_pend_ioから戻った時点で、参照が開放される 2017/12/11訂正)

また、どのca_get要求が未完了なのかを調べるAPIが存在しないので、 以前に未完了で放置したca_get要求が有った場合、直前のca_getが成功したか否かを判定するには、DBR_TIME型などの付加情報の付いた要求を行いbufferが上書きされてるかを判定することになる。

=TCP/IPの接続タイムアウトで接続が遮断すれば、channel状態がDISCONNへ移行し、当該channelへのca_get要求が廃棄されるはずであるが、それまでの間、ca_getへ渡したbufferを安全に回収出来ない=(2017/12/11削除)

=従って、外部ネットワークに悪意があると考えた場合、ca_getはcallback経由の実装を行うべきと思われる=(2017/12/11削除)

ca_get with callbackのアイデア(リソースリーク対策には不要2017/12/11)

callbackへ任意の参照を渡せ、通信が途中で切断された場合はcallbackはbad statusを伴って呼び出されるとの記載があるので、 callbackへ以下の情報を記録したヒープ上のオブジェクトを渡す。

  • main programとの同期変数
  • 読み出しデータの書き込み先の情報

同期変数の状態は以下の4種

  1. main programは、受け取り待ち中(書き込み先情報が有効)
  2. main programは、受け取りを放棄(キャンセル)
  3. main programへ、受け渡し済み(get成功)
  4. main programへ、受け渡し済み(get失敗)

callbackは、同期変数が状態(1)であることを確認し後、データを書き込み、同期変数を状態(3)もしくは(4)へ遷移させる

callbackが、同期変数が状態(2)であることを確認した場合は、ヒープ上のオブジェクトを開放する

main programは、ca_get_callback後に同期変数が状態(3)もしくは(4)へ変わるのをca_pend_ioを行いながら待ち、受け取りに成功した場合は、ヒープ上のオブジェクトを開放する

main programがtimeoutした場合は、同期変数を状態(2)へ遷移させ、受け取り先の割り当てを解除する

callback動作が、プリエンプトな場合は同期変数の操作はアトミックである必要があり、main programとcallbackが併走する場合は、callback側が動作中であることを示す遷移状態かロックを追加する必要がある

ISO C11で同期変数を実装するならatomic_intとか?

2017/12/11追記

ca_get_callbackによる要求に対して、ca_pend_ioはブロッキング動作しないとの事なので、同期待ちがspin waitもしくはsignalベースとなりあまりうれしくないことが判明

ca_sg_create/ca_sg_array_put/ca_sg_blockを使うべきか?

ca_cg_resetで、同期グループ内でissueされている要求をキャンセルできるようなので、安全にリソースを回収できる

ただし、同期グループに複数のI/Oが含まれる場合、どのI/Oが未完で終わったかを識別するAPIが存在しない

  • 生データ以外の例外値が存在する追加データが存在するタイプを要求し、メモリの上書き状態を確かめる
  • 複数の同期グループを構成し、ca_sg_testで個別に調べる
    • 特定の同期グループに対して、ca_sg_blockした際に他の同期グループのタスクが進行するか否かが自明ではない
    • 複数の同期グループを同時に待つAPIが存在しない
      • ca_sg_testと経過時間測定を組み合わせて自前で作成するか、ca_pend_ioとca_sg_testの組み合わせか?
  • 少なくともca_pend_ioでは、同期グループのタスクは進行しない(3.16.1での実験結果)
  • ca_sg_blockがTIMEOUTした時点で、ca_sg_array_get要求がキャンセルされる(3.16.1での実験結果)
  • 特定の同期グループに対するca_sg_blockで他の同期グループのタスクが処理されない場合、効率的に実装する手段が存在しない

従って、ca_get要求が処理されたかを個別に確認するには、以下の2種に絞られる

  • 付加データを含めて要求し、付加データの領域に予め有り得ない値を書き込み、書き換えを検出する
    • dbr_time型であれば、stamp.nsecが使いやすい(有効値 [0, 999999999])
  • callbackベースで実装する。ただし、timeout待ちのblocking waitが面倒

2018-12-08

_ [FreeBSD][雑記]12-PRERELESEへ移行

12.0-RC3も順調なようなので、主要環境をstable/11からstable/12へ切り替え実施

portsのrebuildによるpackage更新がコンパイル約12時間はよいが、portupgradeによる依存性検査に4〜6時間程度かかっているのが頂けない(Core i7 6700)


2019-12-08

_ [SAD]equivalence array VS array pointer

memory allocator更新に向けて、equivalence arrayを参照しているコードを順次array pointer参照に書き換えているが、性能が下がっているっぽい

置き換え前

CompilerFunctionOpticsTrackingMatchingOverall
flang -O30.73760 ± 0.018161.45360 ± 0.012420.55039 ± 0.017730.09693 ± 0.001060.03945 ± 0.00064
gfortran -O30.80652 ± 0.007451.64528 ± 0.011970.54286 ± 0.003750.10905 ± 0.001060.04313 ± 0.00030
  • 使用コンパイラ(以下同様)
    • flang 7.0g20191020
    • gfortran 9.2

*stk置き換え後

CompilerFunctionOpticsTrackingMatchingOverall
flang -O30.81291 ± 0.010021.45929 ± 0.013680.54700 ± 0.003360.09879 ± 0.000830.04128 ± 0.00037
gfortran -O30.86364 ± 0.007001.65001 ± 0.010530.54365 ± 0.004450.10941 ± 0.001230.04455 ± 0.00026

*list置き換え後

CompilerFunctionOpticsTrackingMatchingOverall
flang -O31.15773 ± 0.007001.51878 ± 0.009630.55605 ± 0.005550.10194 ± 0.001100.05024 ± 0.00026
gfortran -O11.15793 ± 0.012061.73687 ± 0.014380.80146 ± 0.009180.11540 ± 0.001220.05521 ± 0.00050
gfortran -O2 -fno-strict-aliasing1.12681 ± 0.011551.75418 ± 0.018130.78415 ± 0.006930.11625 ± 0.001650.05448 ± 0.00046
gfortran -O3 -fno-strict-aliasing1.09313 ± 0.009451.67546 ± 0.012450.54557 ± 0.004130.11088 ± 0.001120.05032 ± 0.00035
  • gfortran -O2/-O3だと途中でSEGVする
    • 独立なポインタ間のメモリーイメージが重複しているが、level 2から有効になる-fstrict-aliasingオプションによって異なる型のarray pointerなので独立しているものとして最適化されている模様
    • そして、ISO Fortranには共用体は標準化されていない
      • ISO Cの共用体は言語仕様レベルで、メモリイメージが共用されることを宣言しているので、strict-aliasingルールの適用外になる
  • WORKAROUND
    • -fno-strict-aliasingでコンパイルする(移植性は無い)
    • 最適化スコープ内で、同一領域に異なる型のポインタによる読み書きを避ける(コードの書き直しが必要/意図が見えにくい)
    • aliasを使わずに、TRANSFERで明示的に変換する(コードの書き直しが必要/煩雑になる)
    • setterを外部手続き・関数化して、最適化スコープを切断する
      • 対象ポインタは common block上に存在するので、呼び出した外部手続き・関数から更新可能。したがって、外部手続き・関数を跨いでarray pointer操作を最適化出来ないはず(未検証)

考察

  • equivalence arrayからarray pointerへの置き換えで、Functionの性能が大きく下がっている
    • オブジェクトコンテナの参照頻度が高いベンチマークで影響が大きい
    • Fortranのarray pointerは、添字の下限・上限及びストライプ幅の概念を持つある種のスマートポインタなので、配列参照に比べて添字計算コストが高い模様(最低でも1乗算・1加算演算増える)

カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記