(前頁)<<      >>(次頁)          (Up)

5章 要素モデルの計算速度調整
      〜 接続線上のレコード数最適化 〜


 
(4)接続線上の最大レコード数の最適化

 前頁で インスタンス生成(new)には時間を要する事を示しました。 接続線上の伝送情報(レコード)も例外では有りません。
 CommonMPでは、接続線上のレコード生成を 少なくするため、「レコードのプール」という仕組みがあります。

 接続線上に前要素モデルが送信したレコードが最大数まで溜ると、次のレコードを送信した時に一番古いレコードから破棄されます。
 しかし、この方法では、送信を行う都度レコードを new する必要が生じます。
 

       
                   ↑ プールが無い時


 CommonMPは、不要となったレコードを破棄しないで、プールクラスが不要となったレコードインスタンスを保持しています。
 新しいレコードが必要となると 新しいレコードを生成する代わりに、プールクラス内で管理されている未使用レコードを再利用します。(プールクラスにレコードが無ければ 新レコードを new します)
 このようにすることで、レコードの new 回数を減らし、計算速度の向上を図っています。
 
 
     
                   ↑ プールでレコードの管理


 計算開始直後から、接続線のレコードが最大数に達するまでは、レコードが生成(new)されます。
 このため 接続線上のレコード最大保持数が大きいと、最大数に達するまではプールの効果が表れません。
 一方で、接続線上の最大レコード保持数が少なすぎると、後要素が必要な情報が取得できなくなる可能性があります。
 CommonMPでは、接続線上の最適なレコード数に調整する機能があります。(Ver1.2以降)


 接続線上のレコード数が多い場合と最適化した場合の計算速度の差を調べてみます。

 テストモデルのDataFusion( )メソッドに レコードを送信する処理を追加します。

protected override long DataFusion(long lOutputDataNum, ref McSendCellDataIF[] csOutputCellData)
{
            HySCellData[] csSndCellData = null;
            HySCellData[,] csSndCellData2 = null;
            HySCellData[,,] csSndCellData3 = null;

            for (long lLp = 0; lLp < lOutputDataNum; lLp++)
            {   // 出力する伝送データ数分繰り返します。
                if (MyExerciseModelDefine.IN_OUT_PATTERN_ANY_D1.Equals(csOutputCellData[lLp].GetID()) == true)
                {
                    csSndCellData = csOutputCellData[lLp].PrepareSendCellD1();
                }
                else if (MyExerciseModelDefine.IN_OUT_PATTERN_ANY_D2.Equals(csOutputCellData[lLp].GetID()) == true)
                {
                    csSndCellData2 = csOutputCellData[lLp].PrepareSendCellD2();
                }
                else if (MyExerciseModelDefine.IN_OUT_PATTERN_ANY_D3.Equals(csOutputCellData[lLp].GetID()) == true)
                {
                    csSndCellData3 = csOutputCellData[lLp].PrepareSendCellD3();
                }
            }
            return 0;
}

  

 下図の様に要素モデルを接続し、各接続線の最大保持レコード数を設定します。

          


 最大レコード数を1000個とした場合と、レコード数を最適化した場合の2種類について、計算期間と計算に要した計算時間を比較してみます。

 尚 使用したPCは DELL社製 LATITUDE D420 
       CPU    Intel Genuine Duo U2500  1.20GHz
           RAM   1.00 GB
           HDD    55GB
          OS   microsoft Windows VISTA
     CommonMP.cfg の ログ出力設定は LOG_LEVEL = TRIAL_RUN 
 です。
 また、要素モデルのδtは全て60秒としてあります。

        

 最大レコード保持数が大きい場合は、計算期間が短い時に、レコード生成に要する時間が非常に影響していることがわかります。 各接続線のレコードが最大数に達した以降の計算時間は プールの効果が現れています。
 不必要に接続線にレコードを保持しておくことは 計算時間の観点からも良くない事がわかります。(特に短期間の計算を行う場合)



接続線のレコード数最適化の説明

 各接続線のレコード数の最適化は下記の様な考え方で行われています。
 
・同期動作の場合
  全体系時間増分:凵A 接続線の前要素モデル時間増分:δ とした時
  レコード数=凵^δ +2  小数以下は切り上げ。
  

・非同期の場合
  (1)全体系時間増分:凵A 接続線の前要素モデル時間増分:δ とした時
     レコード数=凵^δ+2
  (2)接続線の前要素モデル時間増分:δ前 、接続線の後要素モデル時間増分:δ後 としたとき
     レコード数=δ後/δ前 +2
  (3)内部に現状計算型の要素モデルが存在する時
     (3−1)接続線の前側に位置する「現状計算型」要素モデルの中で一番δが大きい値をしらべて、剏サ在型 とする。
     (3−2) レコード数= 剏サ在型/δ後 + 2
  (1),(2),(3)で求めたレコード数の中で最大のレコード数を 最適なレコード数とする。
      (少数以下は切り上げ)

厳密には最適値よりも1〜2レコード余分な大きさになります。

 


(注意)
 一つの要素モデルに対して同じ送信パターンの接続線が複数存在する時には、同じ情報を送信するにも関わらず 各々の接続線に対して、それぞれ異なるレコードのインスタンスが送信されます。
 ところで、上記説明では レコードの生成には時間がかかると述べてきました。 このため、速度最優先ならばレコードのインスタンスを共有し、同じインスタンスを互いの接続線に送信する方が良いかもしれません。
 しかし、速度以上に優先される懸案項目があると判断した為、CommonMPでは敢えて別インスタンスを送信しています。
  

 例えば、上図において 右上の要素モデルが、取得したセル情報を読み出すだけならば 何も問題は発生しませんが、人によっては、取得したセルに対して
   セル.m_dData[0] =  xxxxxx;  
 の様にレコードに書き換えを行うコーディングを(意図して/意図せず にかかわらず)行う可能性が100%無いとは言い切れません。
 すると、レコードのインスタンスを共有している場合には、右下の要素モデルは 左の要素モデルが出力した情報を取得していると思っているにも関わらず別の要素モデルが改変した値を取得してしまうことになります。 このようなバグは ほとんど原因究明不可能なバグとなっていまいます。(特に右上要素モデル開発者以外の使用者にとっては、手も足も出ません) このような可能性を排除するため、CommonMPでは、「必ず接続線毎に 別インスタンスのレコードを生成」しています。 
 さらに、同一送信パターンを複数使用するのはモニター出力等であり、全体の接続線の本数から考えても さほど大きな数ではないと推定し、プールクラスの効力が発揮されれば、計算負荷全体に対する影響の度合いは低いと考えています。
 


(前頁)<<      >>(次頁) 

初版:2013/06/28 |