(57)【要約】【課題】システムＬＳＩの性能の正確な見積もりを行う。【解決手段】性能見積もり装置は、処理の繋がりをノードの繋がりとして表わすタスクグラフで表現されるアプリケーションにおいて、指定されたＲＰＣを実行するＲＰＣノードをシステムＬＳＩに割り当てて、システムＬＳＩにＲＰＣ処理を実行させ、このＲＰＣ処理の実行時のスナップショット２２３１１をシステムＬＳＩに保存する。そして、ＲＰＣノードと、指定された実行周期および繰り返し回数とにより、システムＬＳＩにＲＰＣ処理をパイプライン的に実行させる際に、スナップショット２２３１１に基づいて実行させ、その実行時のプロファイル結果を取得する。【選択図】図３
2020160482.tif 000002
【特許請求の範囲】
【請求項１】
プロセッサ、メモリ、バスを持つホストコンピュータと、プロセッサ、メモリ、バスを持つシステムＬＳＩとが接続された性能見積もり装置において、
処理の繋がりをノードの繋がりとして表わすタスクグラフで表現されるアプリケーションにおいて、指定されたＲＰＣを実行するＲＰＣノードを前記システムＬＳＩに割り当てて、前記システムＬＳＩにＲＰＣ処理を実行させる実行手段と、
前記システムＬＳＩに設けられ、前記ＲＰＣ処理実行時のスナップショットを保存するスナップショット手段と、
前記ＲＰＣノード、指定された実行周期および繰り返し回数、前記スナップショットを基に、前記システムＬＳＩにＲＰＣ処理をパイプライン的に実行させる再実行手段と、
前記再実行手段による実行時の前記システムＬＳＩのプロファイル結果を取得するプロファイル取得手段と、
を具備する性能見積もり装置。
【請求項２】
前記スナップショット手段は、前記ＲＰＣ処理を実行した際の引数の入力履歴を前記スナップショットとして保存する請求項１に記載の性能見積もり装置。
【請求項３】
前記再実行手段は、複数のＲＰＣノードをグループ化して一つのＲＰＣノードとして前記システムＬＳＩに割り当てる請求項１又は２に記載の性能見積もり装置。
【請求項４】
前記再実行手段は、前記システムＬＳＩに、複数のＲＰＣノードを割り当てて、並列に実行させる請求項１又は２に記載の性能見積もり装置。
【請求項５】
性能見積もり対象であるシステムＬＳＩと接続され、プロセッサ、メモリ、バスを持つ端末装置であって、
前記プロセッサは、
処理の繋がりをノードの繋がりとして表わすタスクグラフで表現されるアプリケーションにおいて、指定されたＲＰＣを実行するＲＰＣノードを前記システムＬＳＩに割り当てて、前記システムＬＳＩにＲＰＣ処理を実行させることで、前記システムＬＳＩに、前記システムＬＳＩが前記ＲＰＣ処理を実行した際の引数の入力履歴をスナップショットとして保存させ、
前記ＲＰＣノード、指定された実行周期および繰り返し回数、前記スナップショットを基に、前記システムＬＳＩにＲＰＣ処理をパイプライン的に実行させ、
前記システムＬＳＩから、前記パイプライン的なＲＰＣ処理の実行時の前記システムＬＳＩのプロファイル結果を取得する、
端末装置。
【請求項６】
プロセッサ、メモリ、バスを持つシステムＬＳＩであって、
前記プロセッサは、
ホストコンピュータから、処理の繋がりをノードの繋がりとして表わすタスクグラフで表現されるアプリケーションにおいて、指定されたＲＰＣを実行するＲＰＣノードが割り当てられて、ＲＰＣ処理を実行し、
前記ＲＰＣ処理を実行した際の引数の入力履歴をスナップショットとして前記メモリに保存し、
前記ホストコンピュータから、前記ＲＰＣノードと、指定された実行周期および繰り返し回数とを受けて、ＲＰＣ処理をパイプライン的に実行する際に、前記スナップショットに基づいて実行し、
前記スナップショットに基づく実行時のプロファイル結果を前記ホストコンピュータに送信する、
システムＬＳＩ。
【請求項７】
プロセッサ、メモリ、バスを持つ性能見積もり対象であるシステムＬＳＩと接続された端末装置のプロセッサに、
処理の繋がりをノードの繋がりとして表わすタスクグラフで表現されるアプリケーションにおいて、指定されたＲＰＣを実行するＲＰＣノードを前記システムＬＳＩに割り当てて、前記システムＬＳＩにＲＰＣ処理を実行させることで、前記システムＬＳＩに、前記システムＬＳＩが前記ＲＰＣ処理を実行した際の引数の入力履歴をスナップショットとして保存させる過程と、
前記ＲＰＣノード、指定された実行周期および繰り返し回数、前記スナップショットを基に、前記システムＬＳＩにＲＰＣ処理をパイプライン的に実行させる過程と、
前記システムＬＳＩから、前記パイプライン的なＲＰＣ処理の実行時の前記システムＬＳＩのプロファイル結果を取得させる過程と、
を実行させるプログラム。
【請求項８】
プロセッサ、メモリ、バスを持つシステムＬＳＩのプロセッサに、
ホストコンピュータから、処理の繋がりをノードの繋がりとして表わすタスクグラフで表現されるアプリケーションにおいて、指定されたＲＰＣを実行するＲＰＣノードが割り当てられて、ＲＰＣ処理を実行させる過程と、
前記ＲＰＣ処理を実行した際の引数の入力履歴をスナップショットとして前記メモリに保存させる過程と、
前記ホストコンピュータから、前記ＲＰＣノードと、指定された実行周期および繰り返し回数とを受けて、ＲＰＣ処理をパイプライン的に実行する際に、前記スナップショットに基づいて実行させる過程と、
前記スナップショットに基づく実行時のプロファイル結果を前記ホストコンピュータに送信させる過程と、
を実行させるプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本実施形態は、システムＬＳＩのための性能見積もり装置、端末装置、システムＬＳＩ及びプログラムに関する。
【背景技術】
【０００２】
システムＬＳＩの性能を見積もるために、アプリケーションの一部を実機側にオフロードし、分散実行する（Remote Procedure Call、RPC）ことで、その部分の性能を実機側で計測し、それを足し合わせることで全体の性能を見積もることが行われている。
【０００３】
しかしながら、近年のシステムＬＳＩの主流となっているヘテロジニアスマルチコアプロセッサ（ＨＭＰ）システムにおいて、その上で動く並列ソフトウェアの性能を見積もることは簡単ではない。なぜならば、ＤＳＰやハードウェアアクセラレータ、メモリ、バス等のリソースが競合した場合、並列化されたタスクの実行時間が変動するためである。ＲＰＣの動作状態では、ＲＰＣによるオーバヘッドが存在するため、このリソースの競合状態をうまく表現できず、正確にシステムＬＳＩの性能を見積もることは難しい。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特開２０１７−１０５４０号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
本実施形態は、システムＬＳＩの性能の正確な見積もりを行う。
【課題を解決するための手段】
【０００６】
実施形態の性能見積もり装置は、プロセッサ、メモリ、バスを持つホストコンピュータと、プロセッサ、メモリ、バスを持つシステムＬＳＩとが接続されて構成され。性能見積もり装置は、処理の繋がりをノードの繋がりとして表わすタスクグラフで表現されるアプリケーションにおいて、指定されたＲＰＣを実行するＲＰＣノードを前記システムＬＳＩに割り当てて、前記システムＬＳＩにＲＰＣ処理を実行させる実行手段と、前記システムＬＳＩに設けられ、前記ＲＰＣ処理実行時のスナップショットを保存するスナップショット手段と、前記ＲＰＣノード、指定された実行周期および繰り返し回数、前記スナップショットを基に、前記システムＬＳＩにＲＰＣ処理をパイプライン的に実行させる再実行手段と、前記再実行手段による実行時の前記システムＬＳＩのプロファイル結果を取得するプロファイル取得手段と、を備える。
【図面の簡単な説明】
【０００７】
【図１】実施形態の性能見積もり装置を含む一例のシステムの構成を示す図である。
【図２】ホストＰＣのストレージの一例のデータ構造を示す図である。
【図３】システムにおける処理の概要を示す図である。
【図４Ａ】システムの利用シーケンスを示すフローチャートの前半部分を示す図である。
【図４Ｂ】システムの利用シーケンスを示すフローチャートの後半部分を示す図である。
【図５】ＲＰＣノード作成ＡＰＩの処理シーケンスを示すフローチャートである。
【図６】再実行ＡＰＩの処理シーケンスを示すフローチャートである。
【図７】ノードグルーピングＡＰＩの処理シーケンスを示すフローチャートである。
【図８】システムにおける再実行フェーズにおける処理の概要を示す図である。
【図９】実機ボードの再実行モジュールの処理シーケンスを示すフローチャートである。
【図１０】ワーカスレッドの処理を示すフローチャートである。
【図１１】タイマスレッドの処理シーケンスを示すフローチャートである。
【図１２】システムの効果を説明するための図である。
【図１３】実機ボードにおけるメモリの別の例のデータ構造を示す図である。
【発明を実施するための形態】
【０００８】
以下、実施形態について図面を参照して説明する。なお、以下の説明において、同一の構成要素については同一符号を付すことで説明を省略する。
【０００９】
図１は、実施形態の性能見積もり装置を含む一例のシステムの構成を示す図である。システム１は、ホストＰＣ１０と、実機ボード２０とを有する。ホストＰＣ１０と、実機ボード２０とは、通信インターフェイス３０を介して通信できるように接続されている。通信Ｉ／Ｏとしては、例えばＰＣＩｅ及びＥｔｈｅｒｎｅｔ（登録商標）といったインターフェイスが用いられる。
【００１０】
ホストＰＣ１０は、プロセッサ１１と、ＲＡＭ１２と、操作インターフェイス１３と、ディスプレイ１４と、ストレージ１５とを有する。プロセッサ１１と、ＲＡＭ１２と、操作インターフェイス１３と、ディスプレイ１４と、ストレージ１５とは、バス１６を介して接続されている。
【００１１】
プロセッサ１１は、例えばＣＰＵである。プロセッサ１１は、ホストＰＣ１０における各種の処理をする。プロセッサ１１は、マルチコアのＣＰＵ等であってもよい。
【００１２】
ＲＡＭ１２は、読み書き可能な半導体メモリである。ＲＡＭ１２は、プロセッサ１１による各種の処理の際の作業メモリとして用いられる。
【００１３】
操作インターフェイス１３は、キーボード、マウス等である。操作インターフェイス１３は、ユーザがホストＰＣ１０を操作するためのインターフェイスである。
【００１４】
ディスプレイ１４は、液晶ディスプレイ等である。ディスプレイ１４は、各種の画面を表示する。
【００１５】
ストレージ１５は、例えばハードディスクである。ストレージ１５は、オペレーティングシステム（ＯＳ）、プログラム、ＡＰＩ（Application Programing Interface）等を記憶している。プロセッサ１１は、ストレージ１５に記憶されたプログラム等に従って、これらのプログラムによって指定される機能を実行する。
【００１６】
実機ボード２０の詳細については、後述する。
【００１７】
図２は、ストレージ１５の一例のデータ構造を示す図である。ストレージ１５は、オペレーティングシステム（ＯＳ）１５１と、アプリケーション１５２と、画像処理ライブラリ１５３と、ＲＰＣ（Remote Procedure Call）ライブラリ１５４と、コードジェネレータ１５５と、プロファイラマネージャ１５６を記憶している。なお、ＲＰＣとは、アプリケーションの一部を実機ボード２０にオフロードし分散実行するためのプロトコルである。
【００１８】
ＯＳ１５１は、ホストＰＣ１０の全体の動作を制御するための制御プログラムである。
【００１９】
アプリケーション１５２は、例えば画像認識アプリケーションといった実機ボードに移植されることが想定されたアプリケーションである。アプリケーションは、タスクグラフ（オペレーショングラフ）で表現できるものとする。タスクグラフは、処理（タスク）の繋がりをノードの繋がりとして表現したグラフである。アプリケーション１５２は、画像認識アプリケーションに限るものではない。
【００２０】
画像処理ライブラリ１５３は、画像処理アプリケーションに用いられるライブラリである。画像処理ライブラリ１５３は、例えばＯｐｅｎＶＸといった画像処理フレームワークを有している。また、画像処理ライブラリ１５３は、ノード作成ＡＰＩ１５３１、ＲＰＣノード作成ＡＰＩ１５３２、グラフ作成ＡＰＩ１５３３、実行ＡＰＩ１５３４、再実行ＡＰＩ１５３５を含む。ＡＰＩは、画像処理アプリケーションがＯＳ１５１の機能を利用するためのインターフェイスである。
【００２１】
ノード作成ＡＰＩ１５３１は、アプリケーション１５２の処理をノードとして作成するためのＡＰＩである。一つのノードは、アプリケーション１５２における一つの処理の塊（タスク）を表す。
【００２２】
ＲＰＣノード作成ＡＰＩ１５３２は、ＲＰＣを呼び出すノード（以下、ＲＰＣノード）を作成するためのＡＰＩである。
【００２３】
グラフ作成ＡＰＩ１５３３は、ノード作成ＡＰＩ１５３１又はＲＰＣノード作成ＡＰＩ１５３２を用いて作成されたノードからアプリケーション１５２を表すタスクグラフを作成するためのＡＰＩである。グラフ作成ＡＰＩ１５３３により、アプリケーション１５２のタスクグラフは、全てのノードを含むタスクグラフ（以下、全ノードグラフと称する）と、ＲＰＣノードのみを含むタスクグラフ（以下、ＲＰＣノードグラフと称する）のどちらかで表現される。
【００２４】
ここで、ＲＰＣノードグラフは、全ノードグラフから生成できる。例えば、ユーザは、アプリケーション１５２から実機ボード２０側へ切り出す関数のインターフェイス（関数宣言）をＩＤＬ（Interface Description Language）で記述する。関数のインターフェイスは、関数の引数（例えば、関数群とそれを呼び出すＲＰＣノードの指定）、返り値等を含む。ユーザは、ＲＰＣノード作成ＡＰＩ１５３２を用いて、この切り出した関数のインターフェイスからＲＰＣノードを作成する。ＲＰＣノードは、ＩＤと対応する関数名（複数）、前方依存のノードの数、後方依存ノードのＩＤリストを含む。前方依存のノードとは、依存関係にあるノードのうちの後の方である。後方依存のノードとは、依存関係にあるノードのうちの前の方である。例えば、前のノードの処理結果が後のノードの処理で使用されるときには、後のノードは、前のノードに対して前方依存の関係を有する。ＲＰＣノードグラフはＲＰＣノードの集合である。
【００２５】
実行ＡＰＩ１５３４は、全ノードグラフの処理を実行するためのＡＰＩである。
【００２６】
再実行ＡＰＩ１５３５は、ＲＰＣノードグラフの処理を実行するためのＡＰＩである。再実行ＡＰＩ１５３５は、実行ＡＰＩ１５３４の直後に呼び出される。再実行ＡＰＩ１５３５の引数は、入力周期及び繰り返し回数を含む。入力周期は、再実行がパイプラインで実行される際の源となるＲＰＣノードの実行周期を示す。繰り返し回数は、再実行のときに入力をどれだけ繰り返すかを示す。再実行ＡＰＩの内部処理は、実際には再実行ＲＰＣとして実行される。
【００２７】
また、画像処理ライブラリ１５３は、ＲＰＣノードをグルーピングするためのノードグルーピングＡＰＩ１５３６を有していてもよい。グルーピングされたＲＰＣノードの集合は、このインターフェイスではＲＰＣノードの１つとして処理されてよい。グルーピングがされた場合、グルーピングされているＲＰＣノードは、同一のスレッド上で順番に実行され、並列には実行されない。ノードグルーピングＡＰＩ１５３６は、ホストＰＣ１０の実装状況に応じて、画像処理ライブラリ１５３以外のライブラリに含まれてもよい。
【００２８】
ＲＰＣライブラリ１５４は、ＲＰＣのために用いられるライブラリである。ＲＰＣライブラリ１５４には、コードジェネレータ１５５により、ＲＰＣクライアント１５４１、再実行ＲＰＣクライアント１５４２が生成される。
【００２９】
コードジェネレータ１５５は、ユーザによって記述されたＩＤＬから、ホストＰＣ１０及び実機ボード２０で使用できるコードを生成する。例えば、ユーザによって関数のインターフェイスがＩＤＬで記述されたとき、コードジェネレータ１５５は、ＩＤＬからＲＰＣクライアント１５４１、再実行ＲＰＣクライアント１５４２、ＲＰＣサーバ、再実行ＲＰＣサーバを自動生成する。ＲＰＣクライアント１５４１及び再実行ＲＰＣクライアント１５４２は、ホストＰＣ１０の側に生成される。ＲＰＣサーバ及び再実行ＲＰＣサーバは、実機ボード２０の側に生成される。
【００３０】
プロファイラマネージャ１５６は、実機ボード２０の後述するプロファイラ２２５による計測結果をテキストで又はグラフィカルにディスプレイ１４に表示させる。
【００３１】
アプリケーション１５２は、ＯＳ１５１と画像処理ライブラリ１５３との上で動作するアプリケーションである。前述したように、アプリケーション１５２は、タスクグラフで表現され得る。アプリケーション１５２は、ノード作成ＡＰＩ１５３１及びＲＰＣノード作成ＡＰＩ１５３２を用いたユーザの入力を受けて、各処理を示すノードとＲＰＣノードとを作成し、グラフ作成ＡＰＩ１５３３によりノードの集合からタスクグラフを作成した後、ユーザの入力を受けて実行ＡＰＩ１５３４を呼び出してタスクグラフの処理を実行する。
【００３２】
実機ボード２０は、プロセッサ２１、メモリ２２を有するシステムＬＳＩである。実機ボード２０には、個々のＬＳＩに要される種々のハードウェア２３が実装されている。プロセッサ２１、メモリ２２、ハードウェア２３は、バス２４に接続されている。
【００３３】
プロセッサ２１は、例えばＣＰＵである。プロセッサ２１は、実機ボード２０における各種の処理をする。プロセッサ２１は、マルチコアのＣＰＵ等であってもよい。
【００３４】
メモリ２２は、例えばフラッシュメモリである。メモリ２２は、オペレーティングシステム（ＯＳ）２２１と、画像処理ライブラリ２２２と、ＲＰＣライブラリ２２３と、再実行モジュール２２４と、プロファイラ２２５を記憶している。実機ボード２０では、ＯＳ２２１の上で画像処理ライブラリ２２２及びＲＰＣライブラリ２２３が動作する。
【００３５】
画像処理ライブラリ２２２は、画像処理のためのライブラリを有する。画像処理ライブラリ２２２は、実機ボード２０のハードウェア２３として実装されるハードウェアアクセラレータ、ＤＳＰ（Digital Signal Processor）等に処理をオフロードし得る。
【００３６】
ＲＰＣライブラリ２２３は、ＲＰＣのために用いられるライブラリである。ＲＰＣライブラリ２２３には、ホストＰＣ１０のコードジェネレータ１５５によって、ＲＰＣサーバ２２３１、再実行ＲＰＣサーバ２２３２が生成される。ＲＰＣサーバ２２３１は、ＲＰＣクライアント１５４１から関数処理リクエストを受け取ったときに、関数処理の実装部分を呼び出す。関数の実装部分は、画像処理ライブラリ２２２を呼び出す等することで、ハードウェアアクセラレータ、ＤＳＰ等に処理をオフロードし得る。また、ＲＰＣサーバ２２３１は、初回実行時に、呼ばれた関数のリストの履歴をＲＰＣノード毎に記録する。ここで、関数とＲＰＣノードとの対応関係は、例えばＩＤＬによって記述される。また、ＲＰＣサーバ２２３１は、その時点の状態を丸ごと保存する機能であるスナップショット機能を持つ。つまり、ＲＰＣサーバ２２３１は、呼び出された関数毎に、直前で実行された際の入力（引数、返り値）を取得し、それをスナップショット２２３１１として保存する。
【００３７】
再実行モジュール２２４は、ホストＰＣ１０からの再実行コマンドと、ＲＰＣノードグラフ、入力周期、及び繰り返し回数を受け取り、ＲＰＣノードグラフにおける各ＲＰＣノードの依存関係に基づき、パイプライン的にＲＰＣノードに対応する関数を実行する。すなわち、各ＲＰＣノードに対応する関数を、入力周期毎に、繰り返し回数だけ実行する。ただし、これは、他のＲＰＣノードとの依存関係がないＲＰＣノードについてであり、他のＲＰＣノードとの依存関係があるＲＰＣノードについては、その依存関係を持つＲＰＣノードの実行が終了するまで待機してから、当該ＲＰＣノードに対応する関数を実行する。このように、パイプライン的な実行とは、基本的には各ＲＰＣノードに対応する関数を入力周期毎に繰り返し回数だけ実行するが、他のＲＰＣノードと依存関係がある場合には、依存先の実行終了を待って当該ＲＰＣノードに対応する関数を実行する、ということを意味する。
【００３８】
プロファイラ２２５は、実機ボード２０の最下層で動作する。プロファイラ２２５は、関数の実行時間を計測したり、バスのパフォーマンスモニタ値を取得したりする。プロファイラ２２５は、計測が完了又は計測量が一定量に達すると、ホストＰＣ１０のプロファイラマネージャ１５６に計測結果を送信する。
【００３９】
以下、システム１における処理の流れを説明する。図３は、システム１における処理の概要を示す図である。なお、具体的なフローチャートは後に図４Ａ及び図４Ｂを用いて説明する。
【００４０】
（ＳＴ１）  ユーザは、アプリケーション１５２を起動する。アプリケーション１５２は、ユーザの指示に従ってノード作成ＡＰＩ１５３１及びＲＰＣノード作成ＡＰＩ１５３２を呼び出す。アプリケーション１５２は、ノード作成ＡＰＩ１５３１及びＲＰＣノード作成ＡＰＩ１５３２を用いたユーザの入力を受けてノードを作成する。その後、アプリケーション１５２は、ユーザの指示を受けてグラフ作成ＡＰＩ１５３３を呼び出して全ノードグラフ１５２１を作成する。その後、アプリケーション１５２は、ユーザの操作に従って実行ＡＰＩ１５３４を呼び出し、全ノードグラフ１５２１に従って処理を一旦実行する。図３の全ノードグラフ１５２１において、ノードは円で示され、白抜きの円が通常のノードを表し、色付きの円がＲＰＣノードとしてユーザが指定したノードを表している。ノードの番号は、各ノードを区別するために付したものであり、必ずしも、この順番に処理を行うことを意味していない。ノード間の矢印が、処理の順番を示すとともに、処理結果を利用する依存関係を表している。
【００４１】
通常のノードは、ホストＰＣ１０で実行される。一方、ＲＰＣノードの処理は、実機ボード２０で実行される。つまり、アプリケーション１５２がＲＰＣクライアント１５４１経由で関数を呼び出すと、ＲＰＣクライアント１５４１は、ＲＰＣライブラリ１５４及びＯＳ１５１内の通信用ドライバを経由して実機ボード２０の側のＲＰＣサーバ２２３１に関数処理リクエストを送信する。
【００４２】
ＲＰＣノードの処理が行われると、ＲＰＣサーバ２２３１は、スナップショット機能を用いて、関数毎の入力履歴（関数の引数）をスナップショット２２３１１として保存する。
【００４３】
（ＳＴ２）  以上のように実行ＡＰＩ１５３４を呼んだ後、アプリケーション１５２は、再実行ＡＰＩ１５３５を呼ぶ。アプリケーション１５２は、グラフ作成ＡＰＩ１５３３を呼び出して全ノードグラフ１５２１をＲＰＣノードグラフ１５２２に変換する。そして、アプリケーション１５２は、ＲＰＣノードグラフ１５２２、実行周期、繰り返し回数の組をＲＰＣライブラリ１５４及びＯＳ１５１内の通信用ドライバを経由して実機ボード２０の側の再実行モジュール２２４に渡す。
【００４４】
（ＳＴ３）  再実行モジュール２２４は、スレッドプールの１スレッド当たりに１ノードを割り当て、スナップショット２２３１１として保存しておいた入力履歴を入力としてＲＰＣノードグラフ１５２２の処理を実行させる。図３のスレッドプールにおいて、垂直方向に延びる矢印が各ワーカスレッドを表しており、１つの四角が１つのノードに対応するスレッドである。ここでは、ＲＰＣノードグラフ１５２２の各ＲＰＣノードの番号を付して、スレッドとＲＰＣノードの対応関係を示している。スナップショット２２３１１として保存しておいた入力履歴が入力として使用されるのは、ＲＰＣノードグラフ１５２２が、全ノードグラフ１５２１からの部分グラフであるためである。つまり、依存しているＲＰＣノード間の入出力は必ずしも対応していない。例えば、図３では、ＲＰＣノード３とＲＰＣノード７とは依存関係にある。しかしながら、全ノードグラフ１５２１で見ると、ノード３とノード７との間にはノード５がある。したがって、ＲＰＣノード３の出力はＲＰＣノード７の入力には対応しない。なお、後述するようなグルーピングされたＲＰＣノードは、同一スレッドに割り当てられ、グルーピングされていないＲＰＣノードが複数個あった場合、複数スレッドにそれぞれ割り当てられて並列に実行される。割り当て済みのスレッドにはＲＰＣノードが割り当てられない。なお、１つのスレッドは、例えばプロセッサ２１の１コアに相当する。
【００４５】
各ワーカスレッドの処理は、基本的には実行周期で指定された間隔で実行される。ただし、ＲＰＣノード間に依存関係があるときには、依存関係が解決されるまで、すなわち前方依存のＲＰＣノードの処理が完了するまで、処理は待機される。例えば、図３では、ＲＰＣノード４は、ＲＰＣノード２に対して前方依存の関係を有する。このため、ＲＰＣノード４の処理は、ＲＰＣノード２の処理が完了されるまで待機される。同様に、ＲＰＣノード７は、ＲＰＣノード４とＲＰＣノード３に対して前方依存の関係を有する。このため、ＲＰＣノード７の処理は、ＲＰＣノード４とＲＰＣノード３の両方の処理が完了されるまで待機される。このような各ＲＰＣノードの処理は、繰り返し回数で指定された回数だけ繰り返される。また、ワーカスレッドが枯渇した場合は、枯渇した旨の警告メッセージがホストＰＣ１０のプロファイラマネージャ１５６に送信される。一方、処理はそのまま続行される。
【００４６】
（ＳＴ４）  ワーカスレッドの処理が実行された際のプロファイルは、プロファイラ２２５によって取得される。プロファイラ２２５は、計測が完了又は計測量が一定量に達すると、ホストＰＣ１０のプロファイラマネージャ１５６に計測結果を送信する。プロファイラマネージャ１５６は、実機ボード２０のプロファイラ２２５による計測結果をユーザに対して適切な形で表示させる。
【００４７】
以下、図３で示した流れをより具体的に説明する。図４Ａ及び図４Ｂは、実施形態のシステム１の利用シーケンスを示すフローチャートである。ここで、図３との関係が明確となるよう、図３に示したＳＴ１〜ＳＴ４の符号を併せて記載する。
【００４８】
（ＳＴ１）
ステップＳ１において、ユーザは、アプリケーション１５２を起動し、ノード作成ＡＰＩ１５３１を用いて、実機ボード２０で計測したい関数を取り出す。
【００４９】
ステップＳ２において、ユーザは、取り出した関数を実機ボード２０で実行できるように移植（コーディング）し、ステップＳ３において、ＩＤＬに関数のインターフェイスを記述する。
【００５０】
そして、ステップＳ４において、ユーザは、このＩＤＬをコードジェネレータ１５５に入力する。これにより、コードジェネレータ１５５は、自動的に、実機ボード２０の側にＲＰＣサーバ２２３１を作成し、ホストＰＣ１０の側にはＲＰＣクライアント１５４１を生成する。
【００５１】
ここで、ユーザは、アプリケーション１５２上で、該当ノードを作成するノード作成ＡＰＩ１５３１の呼び出しから、ＲＰＣノードを作成するＲＰＣノード作成ＡＰＩ１５３２の呼び出しに変更する。
【００５２】
図５は、ＲＰＣノード作成ＡＰＩ１５３２の処理シーケンスを示すフローチャートである。図５の処理は、ユーザがアプリケーション１５２においてＲＰＣノード作成ＡＰＩ１５３２を呼び出すと実行される。ステップＳ１０１において、アプリケーション１５２は、通常ノードを作成するＡＰＩであるノード作成ＡＰＩ１５３１を呼び出す。ステップＳ１０２において、アプリケーション１５２は、ユーザによって指定された関数を処理するノードに対し、ＲＰＣを呼び出すノードであることを示すＲＰＣノードフラグを立てる。この後、アプリケーション１５２は、図５の処理を終了させる。
【００５３】
以上の作業が終わったら、図４ＡのステップＳ５において、ユーザは、アプリケーション１５２とＲＰＣクライアント１５４１をホストＰＣ向けコンパイラでコンパイルする。また、ステップＳ６において、関数実体とＲＰＣサーバ２２３１を実機ボード向けコンパイラでコンパイルする。
【００５４】
コンパイルが完了したならば、ステップＳ７において、ユーザは、アプリケーション１５２を一旦実行する。アプリケーションを実行すると、ＲＰＣノードからはＲＰＣが発行され、実機ボード２０の側でそれぞれの関数のプロファイルと入力のスナップショット２２３１１が取られる。アプリケーションの実行が完了すると、プロファイルデータが実機ボード２０のプロファイラ２２５からホストＰＣ１０のプロファイラマネージャ１５６に送信される。
【００５５】
ステップＳ８において、ユーザは、プロファイラマネージャ１５６が可視化したプロファイル結果を確認する。
【００５６】
そして、ユーザは、ステップＳ９において、そのプロファイル結果が予期したような性能を示す結果であるかどうかを判断する。ステップＳ９において、予期した性能が得られていないと判断した場合は、ユーザは、ステップＳ２のコーディングに戻る。予期したような性能が得られたと判断した場合には、ステップＳ１０へ進む。
【００５７】
ステップＳ１０において、ユーザは、実機ボード２０で計測したい処理が一通り揃ったか判断する。ステップＳ１０において、まだ実機ボード２０で計測したい処理が一通り揃っていないと判断した場合には、ユーザは、ステップＳ１に戻る。こうして、処理するＲＰＣノードを増やしていく。ステップＳ１０において、実機で計測したい処理が一通り揃ったと判断した場合には、ステップＳ１１からのパイプライン再実行フェーズに進む。
【００５８】
（ＳＴ２）
このパイプライン再実行フェーズでは、図４ＢのステップＳ１１において、ユーザは、アプリケーション１５２上で、再実行ＡＰＩ１５３５を呼び出す。
【００５９】
図６は、再実行ＡＰＩ１５３５の処理シーケンスを示すフローチャートである。図６の処理は、ユーザがアプリケーション１５２によって再実行ＡＰＩ１５３５を呼び出すと実行される。ステップＳ１１１において、アプリケーション１５２は、グラフ作成ＡＰＩ１５３３を呼び出し、全ノードグラフ１５２１からＲＰＣノードグラフ１５２２を作成する。ＲＰＣノードグラフ１５２２は、単に全ノードグラフ１５２１からＲＰＣノードフラグが立っていないノードを順に削除していくことで得られる。
【００６０】
ステップＳ１１２において、アプリケーション１５２は、ＲＰＣノードグラフ１５２２の表現を画像処理ライブラリ１５３の内部での表現から、ＩＤＬで記述された表現に変換する。
【００６１】
ステップＳ１１３において、アプリケーション１５２は、変換によって得られたＲＰＣノードグラフ１５２２と、ユーザ指定の入力周期、繰り返し回数をリクエストデータに変換する。
【００６２】
ステップＳ１１４において、アプリケーション１５２は、リクエストデータ（ＲＰＣノードグラフ１５２２と、入力周期、繰り返し回数）を引数として再実行ＲＰＣクライアント１５４２及びＯＳ１５１内の通信用ドライバを経由して実機ボード２０の側の再実行モジュール２２４に渡す。
【００６３】
（ＳＴ３）（ＳＴ４）
再実行モジュール２２４は、詳細は後述するように、１スレッド当たりに１ノードを割り当て、スナップショット２２３１１として保存しておいた入力履歴を入力としてＲＰＣノードグラフ１５２２の処理を実行させる。ワーカスレッドの処理が実行された際のプロファイルは、プロファイラ２２５によって取得され、ホストＰＣ１０に送られてくる。
【００６４】
ステップＳ１１５において、アプリケーション１５２は、ＲＰＣによって実機ボード２０から返ってきたレスポンスをそのまま返す。このレスポンスは、例えば、実機ボード２０において各スレッドの処理ができたか否かを示す情報を含む。この後、アプリケーション１５２は、図６の処理を終了させる。
【００６５】
図４Ｂに戻って説明を続ける。ステップＳ１２において、再実行ＡＰＩ１５３５の処理により取得した実機ボード２０からのレスポンスが、プロファイラマネージャ１５６によって、パイプライン処理の結果として可視化して表示され、ユーザはこれを確認する。
【００６６】
そして、ステップＳ１３において、ユーザは、この確認の結果、実機ボード２０において所望の性能が得られているか判断する。ステップＳ１３において、所望の性能が得られていると判断した場合には、ユーザは、図４Ａ及び図４Ｂの処理を終了する。ステップＳ１３において、実機ボード２０の性能が足りないと判断した場合には、ステップＳ１４に処理を進める。
【００６７】
ステップＳ１４において、ユーザは、性能が不足した原因を確認する。
【００６８】
ステップＳ１５において、性能が不足した原因は、ワーカスレッドが枯渇したこと、あいるは、ステージにばらつきがある（ステージに空きがある）ことであったかどうか判断する。ステップＳ１５において、ワーカスレッドが枯渇したこと、あるいは、ステージにばらつきがあることが、性能が不足した原因であると判断した場合には、ユーザは、ステップＳ１６に進む。ステップＳ１５において、その他の原因であると判断した場合には、本質的に実機ボード２０の性能が足りないということである。そのため、バスなどのパラメータ調整を行うか、ＳＩＭＤ（Single Instruction/Multiple Data）等のさらなる最適化をした場合の見積もりをするために実機移植のフェーズに戻るか、アルゴリズムの改変を行うためにリファレンスアプリケーションの修正まで戻る。そして、修正後の実機ボード２０の性能見積もりを行うために、ユーザは、ステップＳ１からの動作を再び行うことになる。
【００６９】
（ＳＴ５）（図８参照）
ステップＳ１６において、ユーザは、ノードグルーピングＡＰＩ１５３６を用いてＲＰＣノードを纏める、つまりグルーピングする。その後、ユーザは、再実行フェーズの先頭であるステップＳ１１に戻り、やり直す。
【００７０】
図７は、ノードグルーピングＡＰＩ１５３６の処理シーケンスを示すフローチャートである。図７の処理は、ユーザがアプリケーション１５２においてノードグルーピングＡＰＩ１５３６を呼び出すと実行される。ステップＳ１２１において、アプリケーション１５２は、ＲＰＣノードが纏められるかどうかを確認する。
【００７１】
ステップＳ１２２において、アプリケーション１５２は、ステップＳ１２１の確認の結果、纏められるか判断する。ステップＳ１２２において、纏められると判断した場合には、アプリケーション１５２は処理をステップＳ１２３に進める。ステップＳ１２２において、纏められないと判断した場合には、アプリケーション１５２は処理をステップＳ１２４に進める。ＲＰＣノード間に、グループ外のＲＰＣノードから又はグループ外のＲＰＣノードへの入力／出力のエッジが含まれている場合は、纏められないと判断する。
【００７２】
ステップＳ１２３において、アプリケーション１５２は、グルーピング先のＲＰＣノードの同一グループリストに、ノードリストを挿入する。この後、アプリケーション１５２は、図７の処理を終了させる。
【００７３】
ステップＳ１２４において、アプリケーション１５２は、エラーコードを返す。この後、アプリケーション１５２は、図７の処理を終了させる。
【００７４】
図８は、システム１における再実行フェーズにおける処理の概要を示す図である。ワーカスレッド数（＝実行コア数）が枯渇している場合や、ステージ実行時間にばらつきがあり、うまく性能を出せていない場合、ユーザは、依存する複数のノードをグルーピングして１つに纏める。
【００７５】
（ＳＴ５）  図８では、ＲＰＣノード６のスレッドの利用率が高くないこと（図３参照）に着目し、ノード６とノード８を纏める例を示している。ノードグルーピングＡＰＩ１５３６にノード６とノード８を引数として実行すると、内部的にはノード６と８を併せた１つのノードとして処理される。
【００７６】
（ＳＴ２’）  その後、アプリケーション１５２は、再実行ＡＰＩ１５３５を呼ぶ。アプリケーション１５２は、グラフ作成ＡＰＩ１５３３を呼び出して全ノードグラフ１５２１をＲＰＣノードグラフ１５２２に変換する。この場合、全ノードグラフにおける１つに纏められたノード６と８が、１つのＲＰＣノードに変換される。そして、アプリケーション１５２は、再び、ＲＰＣノードグラフ１５２２、実行周期、繰り返し回数の組をＲＰＣライブラリ１５４及びＯＳ１５１内の通信用ドライバを経由して実機ボード２０の側の再実行モジュール２２４に渡す。
【００７７】
（ＳＴ３’）  このように、グルーピングして実行された結果、図３に示した再実行フェーズ前の状態に対し１つのワーカスレッドが空くため、ＲＰＣ処理を追加することができる。
【００７８】
図９は、実機ボード２０の再実行モジュール２２４の処理シーケンスを示すフローチャートである。ステップＳ２０１において、再実行モジュール２２４は、ＲＰＣノードグラフ１５２２のＲＰＣノードを先頭から順に取り出す。
【００７９】
ステップＳ２０２において、再実行モジュール２２４は、取り出したＲＰＣノードの中でまだ割り当てられていないＲＰＣノードがあるか否かを判定する。ステップＳ２０２において、取り出したＲＰＣノードの中でまだワーカスレッドに割り当てられていないＲＰＣノードがあると判定されたときには、処理はステップＳ２０３に移行する。ステップＳ２０２において、取り出したＲＰＣノードの中でまだワーカスレッドに割り当てられていないＲＰＣノードがないと判定されたときには、処理はステップＳ２１１に移行する。
【００８０】
ステップＳ２０３において、再実行モジュール２２４は、取り出したＲＰＣノードのうちの１つをワーカスレッドのキューのうちのまだ割り当てられていないものに割り当てる。
【００８１】
ステップＳ２０４において、再実行モジュール２２４は、割り当てをしたＲＰＣノードに対応するmutexを作成する。
【００８２】
ステップＳ２０５において、再実行モジュール２２４は、割り当てをしたＲＰＣノードの依存数が０であるか否かを判定する。すなわちＲＰＣノードの先頭ノードであるか否かを判定する。ステップＳ２０５において、割り当てをしたＲＰＣノードの依存数が０であると判定されたときには、処理はステップＳ２０６に移行する。ステップＳ２０５において、割り当てをしたＲＰＣノードの依存数が０でないと判定されたときには、処理はステップＳ２０８に移行する。
【００８３】
ステップＳ２０６において、再実行モジュール２２４は、mutexを1に初期化する。
【００８４】
ステップＳ２０７において、再実行モジュール２２４は、割り当てをしたＲＰＣノード（先頭ノード）をタイマスレッドで周期的に起動させるノードとして後方依存スレッドのリストに登録する。その後、処理はステップＳ２０９に移行する。つまり、先頭ノードが割り当てられたワーカスレッドは、タイマスレッドの後方依存スレッドになる。
【００８５】
ステップＳ２０８において、再実行モジュール２２４は、mutexを、割り当てをしたＲＰＣノードの依存数（numDep）で初期化する。このmutexは、依存先のワーカスレッドによってデクリメントされる。依存元のワーカスレッドはmutexが0になるまで待つことになる。その後、処理はステップＳ２０９に移行する。
【００８６】
ステップＳ２０９において、再実行モジュール２２４は、ＲＰＣノードの情報と、繰り返し数、mutexを、ＲＰＣノードを割り当てたワーカスレッドに送信する。ＲＰＣノードの情報は、例えばＲＰＣノードのＩＤ、このＲＰＣノードにおいて実行すべき関数群（関数名と関数実体）、このＲＰＣノードの依存数、後方依存スレッドのリストを含む。関数群は、実行される関数毎の名称を示す１つ以上の関数名（funcName）と、関数名と対応する実際に実行される関数の本体である関数実体とを含む。
【００８７】
ステップＳ２１０において、再実行モジュール２２４は、ＲＰＣノードの割り当てが完了したワーカスレッドを起こす。その後、再実行モジュール２２４は、処理をステップＳ２０２に戻す。
【００８８】
ＲＰＣノードの割り当てが完了した後のステップＳ２１１において、再実行モジュール２２４は、実行周期を指定してタイマスレッドを起動する。タイマスレッドの引数としては、繰り返し回数と、後方依存スレッドのリストが与えられる。
【００８９】
ステップＳ２１２において、再実行モジュール２２４は、全てのワーカスレッドの処理が終了するのを待つ。全てのワーカスレッドの処理が終了すると、再実行モジュール２２４は、図９の処理を終了させる。
【００９０】
図１０は、ワーカスレッドの処理を示すフローチャートである。ステップＳ２２１において、ワーカスレッドは、再実行モジュール２２４によって起こされるのを待つ。再実行モジュール２２４によって起こされると、処理はステップＳ２２２に移行する。
【００９１】
ステップＳ２２２において、ワーカスレッドは、キューから処理するＲＰＣノードの情報を取得する。
【００９２】
ステップＳ２２３において、ワーカスレッドは、取得したノード情報からmutexを取り出す。
【００９３】
ステップＳ２２４において、ワーカスレッドは、ＲＰＣノードに対応するmutexが０になる、すなわち前方依存しているノードの処理が全て完了するまで待つ。mutexが０になると、処理はステップＳ２２５に移行する。
【００９４】
ステップＳ２２５において、ワーカスレッドは、mutexを依存数で初期化する。
【００９５】
ステップＳ２２６において、ワーカスレッドは、実行していない関数実体がまだあるか否かを判定する。ステップＳ２２６において、実行していない関数実体がまだあると判定されたときには、処理はステップＳ２２７に移行する。ステップＳ２２６において、実行していない関数実体がないと判定されたときには、処理はステップＳ２３０に移行する。
【００９６】
ステップＳ２２７において、ワーカスレッドは、関数名（funcName）から対応する関数実体を取得する。
【００９７】
ステップＳ２２８において、ワーカスレッドは、取得した関数実体に対応するスナップショット２２３１１を取得する。
【００９８】
ステップＳ２２９において、ワーカスレッドは、関数実体を実行する。その後、ワーカスレッドは、処理をステップＳ２２６に戻す。つまり、関数群に含まれるすべての関数実体が実行されるまで、ステップＳ２２６−Ｓ２２９の処理が繰り返される。
【００９９】
すべての関数実体の処理が完了した後のステップＳ２３０において、ワーカスレッドは、実行回数をカウントアップする。
【０１００】
ステップＳ２３１において、ワーカスレッドは、後方依存している全スレッドのmutexをデクリメントする。
【０１０１】
ステップＳ２３２において、ワーカスレッドは、実行回数と繰り返し回数とが等しいか否かを判定する。ステップＳ２３２において、実行回数と繰り返し回数とが等しくないと判定されたときには、処理はステップＳ２２４に戻る。つまり、処理はmutexが0になるまで待つ処理に戻る。ステップＳ２３２において、実行回数と繰り返し回数とが等しいと判定されたときには、ステップＳ２３３において、ワーカスレッドは処理を完了する。この場合、ワーカスレッドは、処理をステップＳ２２１に戻して再度再実行モジュール２２４から起こされるのを待つ。
【０１０２】
図１１は、タイマスレッドの処理シーケンスを示すフローチャートである。ステップＳ２４１において、タイマスレッドは、指定された実行周期が満了したとき、起動する。
【０１０３】
ステップＳ２４２において、タイマスレッドは、起動回数をインクリメントする。
【０１０４】
ステップＳ２４３において、タイマスレッドは、起動回数と繰り返し回数とが等しいか、つまり起動回数が繰り返し回数に達したか否かを判定する。ステップＳ２４３において、起動回数と繰り返し回数とが等しくないと判定されたとき、処理はステップＳ２４４に移行する。ステップＳ２４３において、起動回数と繰り返し回数とが等しいと判定されたとき、処理はステップＳ２４５に移行する。
【０１０５】
ステップＳ２４４において、タイマスレッドは、後方依存する全スレッドのmutexをデクリメントする。その後、タイマスレッドは、処理をステップＳ２４１に戻す。
【０１０６】
ステップＳ２４５において、タイマスレッドは、図１１の処理を終了させる。
【０１０７】
以上説明したような実施形態によれば、システムＬＳＩの性能のより正確な見積もりを行うことが可能となる。図１２は、この効果を説明するための図である。ホストＰＣ１０上でアプリケーション１５２を構築し、その後、ＲＰＣを使って主要要素の実機ボード２０における処理時間を計測すると、図１２の上側に示すように、最終的な製品に移植かつ並列化されたアプリケーションの動作状態とは乖離が大きいため、十分に見積もれた状態とは言いがたい。ここで、垂直方向に延びる矢印が各ワーカスレッドを表しており、白抜きの四角がアプリケーションの通常ノードに対応するスレッドを示し、色付きの四角がＲＰＣノードに対応するスレッドを示している。本実施形態では、依存元のノードの出力結果を使うのではなく、スナップショットを用いることで、図１２の下側に示すように、リソース競合する並列処理を再現し、プロファイリングすることができる。そして、そのプロファイリングに基づいて、ＲＰＣノードのグルーピングを行って空き処理時間を減少させる。これにより空きのワーカスレッドが得られれば、そこに更にＲＰＣノードに対応するスレッドを割り当てて、再度、並列処理を再現・プロファイリングすることができる。このように、実機ボード２０上にオフロードされた複数の処理をパイプライン的に再構成し、リソース競合する並列処理を再現・プロファイリングすることで、図１２の下側に示すように、製品に実装したときの性能をより正確に見積もりすることが可能になる。
【０１０８】
したがって、先行開発の段階、すなわちアプリケーション１５２の実機ボード２０上への移植が行われておらず、パイプライン並列化もされていない段階において、アプリケーション１５２がパイプライン並列化され実機ボード２０で実行された場合の性能を、より正確に（具体的には、メモリ２２やバス２４、アクセラレータ等のハードウェア２３、等のリソース競合を含めて）見積もることが可能となる。
【０１０９】
また、パイプライン的に再構成した結果に基づいて、ＲＰＣノードをグルーピングして、再度、見積もりを行うことができる。
【０１１０】
なお、実機ボード２０は、図１に示したようなＯＳ２２１を持つものに限定されるものではなく、ＯＳ２２１を持たず、ボードサポートパッケージ（ＢＳＰ）のような最小限のランタイムを持つ場合にも適用可能である。図１３は、このような実機ボード２０におけるメモリ２２の一例のデータ構造を示す図である。メモリ２２は、ボードサポートパッケージ２２６と、画像処理ライブラリ２２２と、ＲＰＣライブラリ２２３と、再実行モジュール２２４と、プロファイラ２２５を記憶している。この場合、ランタイムはマルチスレッドやマルチタスキングの機能を持たないため、パイプライン処理は、コア又はプロセッサ２１をスレッドに見立てて実行される。また、プロファイラ２２５は、ハイパーバイザとして構成しても良い。
【０１１１】
本発明のいくつかの実施形態を説明したが、これらの実施形態は、例として提示したものであり、発明の範囲を限定することは意図していない。これら新規な実施形態は、その他の様々な形態で実施されることが可能であり、発明の要旨を逸脱しない範囲で、種々の省略、置き換え、変更を行うことができる。これら実施形態やその変形は、発明の範囲や要旨に含まれるとともに、特許請求の範囲に記載された発明とその均等の範囲に含まれる。
【符号の説明】
【０１１２】
１…システム、１０…ホストＰＣ、１１，２１…プロセッサ、１２…ＲＡＭ、１３…操作インターフェイス、１４…ディスプレイ、１５…ストレージ、１６，２４…バス、２０…実機ボード、２２…メモリ、２３…ハードウェア、１５１…オペレーティングシステム、１５２…アプリケーション、１５３…画像処理ライブラリ、１５４…ＲＰＣライブラリ、１５５…コードジェネレータ、１５６…プロファイラマネージャ、２２１…オペレーティングシステム、２２２…画像処理ライブラリ、２２３…ＲＰＣライブラリ、２２４…再実行モジュール、２２５…プロファイラ、２２６…ボードサポートパッケージ、１５３１…ノード作成ＡＰＩ、１５３２…ＲＰＣノード作成ＡＰＩ、１５３３…グラフ作成ＡＰＩ、１５３４…実行ＡＰＩ、１５３５…再実行ＡＰＩ、１５３６…ノードグルーピングＡＰＩ、１５４１…ＲＰＣクライアント、１５４２…再実行ＲＰＣクライアント、２２３１…ＲＰＣサーバ、２２３２…再実行ＲＰＣサーバ、１５２１…全ノードグラフ、１５２２…ＲＰＣノードグラフ、２２３１１…スナップショット。
【図１】
2020160482.tif 000003
【図２】
2020160482.tif 000004
【図３】
2020160482.tif 000005
【図４Ａ】
2020160482.tif 000006
【図４Ｂ】
2020160482.tif 000007
【図５】
2020160482.tif 000008
【図６】
2020160482.tif 000009
【図７】
2020160482.tif 000010
【図８】
2020160482.tif 000011
【図９】
2020160482.tif 000012
【図１０】
2020160482.tif 000013
【図１１】
2020160482.tif 000014
【図１２】
2020160482.tif 000015
【図１３】
2020160482.tif 000016