FabricStatistics エクステンション

../../_images/FE_logo_345_60.png
Fabric Engine version 2.4.0
Copyright (c) 2010-2017 Fabric Software Inc. All rights reserved.

FabricStatistics エクステンションはカスタム統計やプロファイリング情報を効率よく収集し統合できるシングルトン統計コレクターをラップしています。スレッドセーフなシングルトンを通して、統計ソースオブジェクトおよびプロファイリングイベントはKLコードからいつでも記録ができます。

FabricStatisticsエクステンションは、オーバーヘッドを最小限に抑えることと使用の簡易さが両立するように設計されています。特に、統計分析およびイベントプロファイリングのための大半の作業が、最終のレポートが要求されるまで遅延されます。

統計(Statistics)

FabricStatisticsエクステンションは任意のKLソースコード(エクステンションやオペレーターなど)からカスタム統計や登録済みオブジェクトの情報を収集できます。 それはレポートを単純化するオブジェクト階層をサポートし、階層の値を合計することができます (例:メモリ使用量)。

オブジェクトの統計収集は StatisticSource インターフェースの実装を通じて有効になります。 StatisticSource.getStatistics メソッドを通じて、オブジェクトは分析の促進に役立つ任意の統計や情報を出力できます。 StatisticSource の実装は、次の例に見られるように StatisticsAutoRegisterMember ヘルパーオブジェクトの使用によって簡略化できます。

FabricStatisticsエクステンションで登録するためには、 StatisticSource インターフェースを実装するオブジェクトがコンストラクタで RegisterToFabricStatistics を、そしてデストラクタで UnregisterFromFabricStatistics を呼び出す必要があります。このプロセスも StatisticsAutoRegisterMember ヘルパーの使用によってより堅牢性を高め、かつ簡略化ができます。

統計元オブジェクト群は、 EnableFabricStatistics 関数の呼び出しによって前もって統計が有効にになっている場合にのみ記録されます。 EnableFabricStatistics の呼び出しの前に構成された統計元オブジェクト群は監視されなくなるので、シーンの読み込み前に統計を有効にすることをお勧めします。

もし StatisticSource がそれら自身 StatisticSource のサブオブジェクト群を持っている場合、(例:「ポリゴンメッシュ」は「ジオメトリアトリビュートコンテナ」を持っている)この関係は AddStatisticsChild 関数の呼び出しによって明示的に記録される必要があります。

警告

デストラクタでのオブジェクトの登録解除の失敗は、FabricStatisticsエクステンションがリーク(他にもオブジェクトが破棄されない)を回避するためのオブジェクトの Ref<> (所有しない)を維持するので、クラッシュの原因となります。またしても、これは StatisticsAutoRegisterMember ヘルパーの使用で回避できます。

StatisticSource.getStatistics メソッドを経たオブジェクトによって返された統計は StatisticRecord で埋め込まれた単純な名前と値のペアです。サポートされる統計値の型は`文字列`、`SInt64`と`Float64`が含まれます。とはいえ返される統計値は任意(例:’イメージ’では’幅’と’高さ’で返す)にできますが、それぞれ標準のフィールドがあります。

  • 「名前」( Statistic_Name 定数): 統計レポート内でオブジェクトを識別する最善の方法として、名前を与えておくべきです。
  • 「カテゴリ」( Statistic_Category 定数): より明瞭になるよう統計レポート内の異なる型のオブジェクト群を再グループ化することを可能にします
  • 「タイプ」( Statistic_Type 定数): ソースのKL型。 .type() KL機能を使用して自動的に生成されるので、これは与える必要はありません。統計レポートがより明瞭になるように、同じ型のオブジェクトを再グループ化できます。
  • 「メモリ」( Statistic_MemoryUsage 定数): オブジェクトのために使用するメインメモリ。オブジェクトが自身でStatisticSourceインターフェースを実装したサブオブジェクトを所有する場合、メモリ内に含めるのではなくむしろ( AddStatisticsChild 関数を使用し)子供オブジェクトとして設定するべきです。標準的に、メモリ統計は最終レポート内で階層を加算します。KLで実際のメモリ使用量の情報を引き出すための機能をまだ提供しておらず、手動で見積もる必要があります。
  • 「GPUメモリ」( Statistic_GPUMemoryUsage 定数): メモリ(上記参照)と同じですが、GPUのためのものです。(例えば: OpenGLバッファーオブジェクト)
require FabricStatistics;

object MyObject : StatisticSourceWithAutoRegisterMember {
    String name;
    Float32 scalars[];

    StatisticsAutoRegisterMember autoStats;
  };

function MyObject() {
  if( FabricStatisticsEnabled() ) //Reduce overhead if stats are turned off
    this.autoStats = StatisticsAutoRegisterMember(this);
}

function StatisticRecord[] MyObject.getStatistics() {
  StatisticRecord stats[];
  stats.push(StatisticRecord(Statistic_Name, this.name));
  stats.push(StatisticRecord(Statistic_MemoryUsage, this.scalars.size()*4 ));
  return stats;
}

operator entry() {

  EnableFabricStatistics();

  MyObject obj1();
  obj1.name = "obj1";
  obj1.scalars.resize(10);

  MyObject obj2();
  obj2.name = "obj2";
  obj2.scalars.resize(20);

  MyObject obj3();
  obj3.name = "obj3";
  obj3.scalars.resize(30);

  //Make obj3 a children of obj2
  AddStatisticsChild(obj2.autoStats, obj3.autoStats);

  report( GetStatisticsReport() );
}

/*
** Output:

Name="obj1" Memory=40 Type="MyObject"
Name="obj2" Memory=80 MemorySum=200 Type="MyObject"
  Name="obj3" Memory=120 Type="MyObject"


*/

全ての登録済みオブジェクトやそれら階層の統計は GetStatisticStringsGetStatisticsCSV といった関数を呼び出すことで情報を引き出す(検索する)ことができます。ランタイムオーバーヘッドを最小限に抑えるために、統計元オブジェクトの StatisticSource.getStatistics メソッドは統計レポートが構築される時に呼び出さるだけです。破棄したオブジェクト群についての情報は保持されません。

レポートはいくつかの統計の合計を生成できます(例:メモリ)。オブジェクト階層を合計するための統計のリストは、 GetStatisticStrings のような関数の ColumnsToSum 引数によって提供されます。

注釈

FabricStatistics_RTValWrapper オブジェクトは FabricStatistics のグローバル関数群をシンプルにラップし、それらは RTVals を通じてアクセスすることができます。(グローバル関数は制限のためアクセス不可です)

プロファイリング

FabricStatisticsエクステンションは、カスタムプロファイリングイベント群を記録するためのいくつかの機能を提供します。FabricStatisticsプロファイルイベント群は、たとえばオペレータをタグで識別された複数のステップに分割するといった特定の詳細についての追跡で役立ちます。FabricStatisticsプロファイルイベント群は入れ子にすることができ、イベント群の階層は記録されます。

出力済みのプロファイリングイベント群は、プロファイリングが StartFabricProfiling もしくは StartFabricProfilingFrames の呼び出しによって有効にされた場合に記録されるだけです。

プロファイリングイベントは BeginProfilingEventEndProfilingEvent の呼び出しをひとまとめで行う必要があります。 BeginProfilingEvent で返された key は、 EndProfilingEvent まで渡す必要があります。このような時には、イベント群はより多くの情報を提供するために StatisticSource を参照することができます。 AutoProfilingEvent 定数は破棄する際に EndProfilingEvent を自動で呼び出すので、プロファイリングイベント群の記録を簡略化できます。

最後のプロファイリングセッションの全ての記録済みイベント群は、 GetProfilingEvents もしくは GetProfilingReport の呼び出しで回収できます。

/*
** Example: CPUProfiling.kl
*/

require FabricStatistics;

function sub2() {
  AutoProfilingEvent p(FUNC);//We use the 'FUNC' built-in KL constant (name of current function)
  ActiveWait(0.25);
}

function sub1() {
  AutoProfilingEvent p(FUNC);//We use the 'FUNC' built-in KL constant (name of current function)
  ActiveWait(0.25);
  sub2();
}

function main() {
  AutoProfilingEvent p(FUNC);//We use the 'FUNC' built-in KL constant (name of current function)
  ActiveWait(0.25);
  sub1();
}

operator entry() {

  StartFabricProfiling();
  main();
  StopFabricProfiling();

  report( GetProfilingReport() );

  ProfilingEvent events[](GetProfilingEvents ());
  for(Integer i=0; i<events.size(); i++)
    report( events[i] );
}

/*
** Output:

function main(): duration=750.7493477 ms, startTime=+1.200777e-6', threadIndex:0
  function sub1(): duration=500.4995337 ms, startTime=+0.250063', threadIndex:0
    function sub2(): duration=250.2497623 ms, startTime=+0.500079', threadIndex:0

{level:0,frame:0,label:"function main()",startTime:+1.200777142966928e-6,duration:+0.750098463725723,sourceName:"",threadIndex:0}
{level:1,frame:0,label:"function sub1()",startTime:+2.500636411885772e-1,duration:+0.500034222148574,sourceName:"",threadIndex:0}
{level:2,frame:0,label:"function sub2()",startTime:+0.500079551485721,duration:+2.500126081600011e-1,sourceName:"",threadIndex:0}

*/

索引と検索