(57)【特許請求の範囲】
【請求項１】
メインプロセッサと複数のコプロセッサを含むシステムにおいて実行される並列動作用のプログラムコードを生成する設計支援装置であって、
同期条件を有し、スレッドから同期を求められた際に、前記同期条件が成立するまで前記スレッドの実行を遅延させる同期クラスと、前記コプロセッサの制御を行うノードクラスを記憶する記憶部と、
前記複数のコプロセッサに対応付けられた複数のスレッドの連携を規定する有向グラフを、前記複数のコプロセッサの制御を表すノードオブジェクトと、前記複数のスレッドの各々を示すノードオブジェクトと、前記同期クラスを示す同期オブジェクトとに基づいて、前記複数のスレッドに含まれるデータの入出力関係を有する２以上のスレッドのうち、前記入出力関係の入力側となるスレッドを示すノードオブジェクトと、前記入出力関係の出力側となるスレッドを示すノードオブジェクトとの間を、前記同期オブジェクトを介して接続する接続記述により定義した、利用者が作成したプログラムコードを取得し、
取得した前記プログラムコードと、前記記憶部に記憶された前記同期クラスと前記ノードクラスとを組み合わせて、前記並列動作用のプログラムコードを生成する制御部と、
を有することを特徴とする設計支援装置。
【請求項２】
前記複数のスレッドを同期した実行履歴を出力する出力手段を有することを特徴とする請求項１に記載の設計支援装置。
【請求項３】
前記スレッドが前記コプロセッサを制御する場合であって、
前記コプロセッサが送信した割り込みを前記スレッドに出力する出力手段を有し、
前記制御部は、
割り込み識別番号と前記スレッドを関係づける情報に基づいて、前記割り込みの対象となる前記ノードオブジェクトを参照することにより、前記コプロセッサが送信した割り込みを前記スレッドに出力することを特徴とする請求項１に記載の設計支援装置。
【請求項４】
前記割り込み、または、前記複数のスレッドを同期した実行履歴を出力する出力手段を有することを特徴とする請求項３に記載の設計支援装置。
【請求項５】
出力した前記実行履歴を解析して、前記スレッドの状態の変化を示す図を表示する表示手段を有することを特徴とする請求項２または請求項４に記載の設計支援装置。
【請求項６】
メインプロセッサと複数のコプロセッサを含むシステムにおいて実行される並列動作用のプログラムコードを生成するための設計支援方法であって、
同期条件を有し、スレッドから同期を求められた際に、前記同期条件が成立するまで前記スレッドの実行を遅延させる同期クラスと、前記コプロセッサの制御を行うノードクラスを記憶し、
前記複数のコプロセッサに対応付けられた複数のスレッドの連携を規定する有向グラフを、前記複数のコプロセッサの制御を表すノードオブジェクトと、前記複数のスレッドの各々を示すノードオブジェクトと、前記同期クラスを示す同期オブジェクトとに基づいて、前記複数のスレッドに含まれるデータの入出力関係を有する２以上のスレッドのうち、前記入出力関係の入力側となるスレッドを示すノードオブジェクトと、前記入出力関係の出力側となるスレッドを示すノードオブジェクトとの間を、前記同期オブジェクトを介して接続する接続記述により定義した、利用者が作成したプログラムコードを取得し、
取得した前記プログラムコードと、前記記憶部に記憶された前記同期クラスと前記ノードクラスとを組み合わせて、前記並列動作用のプログラムコードを生成する、ことを特徴とする設計支援方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、設計支援装置、および設計支援方法に関する。
【背景技術】
【０００２】
従来、複数のスレッドが連携して並列に動作するソフトウェアプログラムを開発する場合に、開発者が、データフローなどの仕様を決定し、決定した仕様に基づきコーディングする。
【０００３】
また、従来、車両用プログラム開発を支援するために、データフローチャートのシンボルブロックに整数情報をもたせ、整数情報を利用して整数ロジックの車両用Ｃコードを自動生成する技術が公知である（例えば、以下特許文献１参照。）。
【０００４】
また、従来、制御仕様を記述したデータフロー図に基づき制御処理プログラムを自動生成する場合についても排他制御を可能にする技術が公知である（例えば、以下特許文献２参照。）。
【０００５】
また、従来、データフロー図から演算装置固有の拡張機能を利用するプログラムの実装コードを生成する技術が公知である（例えば、以下特許文献３参照。）。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２０００−２０２９１号公報
【特許文献２】特開２００３−７６５４７号公報
【特許文献３】特開２００８−３８１７号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
しかしながら、複数のスレッドを連携させる制御は複雑であるため、複数のスレッドが連携して並列に動作するソフトウェアプログラムを仕様に基づきコーディングすることは困難である。同様に、複数のスレッドを連携させる制御は複雑であるため、複数のスレッドが連携して並列に動作するソフトウェアプログラムの仕様を作成することも困難である。
【０００８】
１つの側面では、本発明は、並列動作用のソフトウェアの作成の容易化を図ることができる設計支援装置、および設計支援方法を提供することを目的とする。
【課題を解決するための手段】
【０００９】
本発明の一側面によれば、入力される複数のスレッドを同期する際の同期条件を記憶し、前記複数のスレッドに対して、前記同期条件に応じた制御を同期手段が行い、利用者が作成する前記複数のスレッドと、前記複数のスレッドのそれぞれと前記同期手段を関係づける記述情報と、に基づいてソフトウェアを生成する、設計支援装置、および、設計支援方法が提案される。
【発明の効果】
【００１０】
本発明の一態様によれば、並列動作用のソフトウェアの作成の容易化を図ることができる。複数スレッドの連携制御（例えば、データフロー制御）に適した手段を提供しているので、ソフトウェア開発コストの削減を図ることができる。ソフトウェア内で複数スレッドの連携動作（例えば、データフロー動作）が実現されるので、実機上でも複数スレッドの連携が動作することになり、実機におけるデバッグの容易化を図ることができる。最終的なソフトウェアと同じ、複数スレッドの連携制御（例えば、データフロー制御）を、コンピュータ上で実行し、直観的に理解することができる。このため、抽象的なシミュレーションとして仕様検討に利用できるので、複数スレッドの連携制御の仕様検討にかかる工数の削減を図ることができる。結果的に、仕様検討から実機デバッグまでを、本質的には、同一の、複数スレッドの連携制御（例えば、データフロー制御）をもつ、ソフトウェアで実行できるので、開発コスト削減と、結果の比較分析と、の容易化を図ることができる。以上のように、ソフトウェア開発の様々な面で、ソフトウェアの作成の容易化を図ることができる。
【図面の簡単な説明】
【００１１】
【図１Ａ】図１Ａは、設計支援装置による一動作例を示す説明図（その１）である。
【図１Ｂ】図１Ｂは、設計支援装置による一動作例を示す説明図（その２）である。
【図１Ｃ】図１Ｃは、設計支援装置による一動作例を示す説明図（その３）である。
【図２】図２は、ソフトウェア開発フロー例を示す説明図である。
【図３】図３は、ガントチャートとシーケンス図の一例を示す説明図である。
【図４】図４は、本実施の形態と従来技術との簡単なフローによる処理の比較例を示す説明図である。
【図５】図５は、設計支援装置のハードウェア構成例を示すブロック図である。
【図６】図６は、設計支援装置の機能的構成例を示すブロック図である。
【図７】図７は、データフロー例を示す説明図である。
【図８】図８は、データフローのモデル化例を示す説明図である。
【図９】図９は、ノードオブジェクト例を示す説明図である。
【図１０】図１０は、ノードクラス例を示す説明図である。
【図１１】図１１は、ノードクラスの詳細例を示す説明図である。
【図１２】図１２は、同期オブジェクト例を示す説明図である。
【図１３】図１３は、同期クラスｓｙｎｃ＿ｔのメンバー関数ｓｙｎｃ（）を示す説明図である。
【図１４】図１４は、同期クラス例を示す説明図である。
【図１５】図１５は、データフローの記述例を示す説明図である。
【図１６】図１６は、実行例を示す説明図である。
【図１７】図１７は、同期オブジェクトの利用例を示す説明図である。
【図１８Ａ】図１８Ａは、同期オブジェクトの動作例を示す説明図（その１）である。
【図１８Ｂ】図１８Ｂは、同期オブジェクトの動作例を示す説明図（その２）である。
【図１８Ｃ】図１８Ｃは、同期オブジェクトの動作例を示す説明図（その３）である。
【図１８Ｄ】図１８Ｄは、同期オブジェクトの動作例を示す説明図（その４）である。
【図１８Ｅ】図１８Ｅは、同期オブジェクトの動作例を示す説明図（その５）である。
【図１９】図１９は、同期処理のシーケンス例を示す説明図である。
【図２０】図２０は、ガントチャートの表示例を示す説明図である。
【図２１】図２１は、実行履歴を記憶するための記述例を示す説明図である。
【図２２】図２２は、分析作業の支援例を示す説明図である。
【図２３】図２３は、設計支援装置が行う処理手順例を示すフローチャートである。
【図２４】図２４は、ノードの基本クラスの記述例を示す説明図である。
【図２５】図２５は、ノードクラスと割り込み例を示す説明図である。
【図２６】図２６は、割り込みとノードとの対応表例を示す説明図である。
【図２７】図２７は、同期例を示す説明図である。
【図２８Ａ】図２８Ａは、同期クラスと同期ポートクラスの詳細例を示す説明図（その１）である。
【図２８Ｂ】図２８Ｂは、同期クラスと同期ポートクラスの詳細例を示す説明図（その２）である。
【図２９Ａ】図２９Ａは、同期クラスと同期ポートクラスの詳細例を示す説明図（その３）である。
【図２９Ｂ】図２９Ｂは、同期クラスと同期ポートクラスの詳細例を示す説明図（その４）である。
【図３０】図３０は、ｓｏｕｒｃｅ＿ｔの記述例を示す説明図である。
【図３１】図３１は、ｐａｌａ＿ｔおよびｓｏｌｏ＿ｔの記述例を示す説明図である。
【図３２】図３２は、ｓｉｎｋ＿ｔの記述例を示す説明図である。
【図３３】図３３は、ノードの接続記述例を示す説明図である。
【図３４】図３４は、ｄａｔａ＿ｔの記述例を示す説明図である。
【図３５Ａ】図３５Ａは、実行によって得られる標準出力例を示す説明図（その１）である。
【図３５Ｂ】図３５Ｂは、実行によって得られる標準出力例を示す説明図（その２）である。
【図３５Ｃ】図３５Ｃは、実行によって得られる標準出力例を示す説明図（その３）である。
【図３６】図３６は、ｓｏｕｒｃｅ＿ｔの他の記述例を示す説明図である。
【図３７】図３７は、ノードの接続記述の他の例を示す説明図である。
【図３８】図３８は、ｉｎｔｅｒｒｕｐｔ＿ｔの記述例を示す説明図である。
【図３９】図３９は、実行によって得られる標準出力の他の例を示す説明図である。
【図４０】図４０は、段階的な設計フロー例を示す説明図である。
【図４１】図４１は、ガントチャート作成のための追加記述例を示す説明図である。
【図４２】図４２は、ガントチャート作成のための接続記述例を示す説明図である。
【図４３Ａ】図４３Ａは、図４１および図４２に示した記述情報に基づく実行結果例を示す説明図（その１）である。
【図４３Ｂ】図４３Ｂは、図４１および図４２に示した記述情報に基づく実行結果例を示す説明図（その２）である。
【図４３Ｃ】図４３Ｃは、図４１および図４２に示した記述情報に基づく実行結果例を示す説明図（その３）である。
【図４３Ｄ】図４３Ｄは、図４１および図４２に示した記述情報に基づく実行結果例を示す説明図（その４）である。
【図４３Ｅ】図４３Ｅは、図４１および図４２に示した記述情報に基づく実行結果例を示す説明図（その５）である。
【図４４】図４４は、接続関係の記述例を示す説明図である。
【図４５】図４５は、作成されるガントチャート例を示す説明図である。
【図４６Ａ】図４６Ａは、印字回数を増やした記述例を示す説明図（その１）である。
【図４６Ｂ】図４６Ｂは、印字回数を増やした記述例を示す説明図（その２）である。
【図４６Ｃ】図４６Ｃは、印字回数を増やした記述例を示す説明図（その３）である。
【図４７】図４７は、図４６Ａ〜図４６Ｃの記述情報に基づく実行結果例を示す説明図である。
【図４８Ａ】図４８Ａは、印字回数を増やした他の記述例を示す説明図（その１）である。
【図４８Ｂ】図４８Ｂは、印字回数を増やした他の記述例を示す説明図（その２）である。
【図４８Ｃ】図４８Ｃは、印字回数を増やした他の記述例を示す説明図（その３）である。
【図４９】図４９は、図４８Ａ〜図４８Ｃの記述情報に基づく実行結果例を示す説明図である。
【発明を実施するための形態】
【００１２】
以下に添付図面を参照して、本発明にかかる設計支援装置、および設計支援方法の実施の形態を詳細に説明する。
【００１３】
図１Ａ〜図１Ｃは、設計支援装置による一動作例を示す説明図である。設計支援装置１００は、複数のスレッドが連携して並列動作する際の制御を行う並列動作用のソフトウェアの作成を支援するコンピュータである。
【００１４】
従来、開発者が、データフローやデータフローに基づきガントチャートなどの詳細な仕様を決定した後に、並列動作用のソフトウェアを作成しなければならなかった。そのため、開発者は複数の並列に動作する並列動作処理を行うソフトウェアを作成するのが困難である。データフローとは、処理を表すノード集合と、データ送信元ノードから送信先ノードへの矢印集合で定義される、有向グラフのことである。通例、ノードは並列に動く。並列に動作する処理のことをスレッドとも呼ぶ。本実施の形態では、データフロー制御を例とするが、本質的には、複数ノード、換言すると、複数スレッドの連携制御の一事例として、データフロー制御の例を示している。本発明における、ノードとは、実装上は、スレッドとスレッドに渡す変数値をオブジェクト化したものを指している。このため、以下の説明では、文脈によって、ノードのことを、スレッドとよんでいることがある。
【００１５】
１０１に、開発者の頭の中のイメージ例を示す。本設計支援装置１００は、開発者の直観に近い開発を行える環境を提供するものである。効率的な開発をするためには、直観的に開発できることが必要である。そのため、開発方法において要求する入力が、開発者のイメージに近いことが望ましい。そこで、最初に、開発者が有するイメージを想定したい。開発者は、まず、機能を思い浮かべるはずである。つぎに、この機能を実現するために必要な機能を見つける。例えば、開発者は、すべてコプロセッサで実装し、コプロセッサは、コプロセッサ０〜３を使おう、と決める。つぎに、全体の機能を得るためにはデータのやり取りが必要であるため、開発者はデータフロー図について思考することが推測される。データフロー図は例えばイメージ１０１中の左側の図である。データフローを実現するために、コプロセッサ間でのデータやり取りが必要になる。そこで、例えば、本実施の形態では、ダブルバッファを用意する。ダブルバッファは、イメージ１０１中の右側の図である。このようにして、開発者は、ソフトウェアの開発時に大まかな実現イメージを持つことが想定される。複数のスレッドを連携させて１つの機能を実現することを考える場合、複数スレッドの連携全般において、このような発想をすると推測できる。しかし、従来の実現方法では、このイメージをさらに詳細化する必要があった。例えば、実現方法の一例については、図２に示す。
【００１６】
そこで、本実施の形態では、開発者のイメージに近い入力を可能にする枠組みを予め用意する。枠組みでは、部品を用意する。部品は、１０２ａｂｃであり、記憶部１０２にテンプレートが記憶される。部品１０２ａｂｃは、同期クラス１０２ａ、同期ポートクラス１０２ｂ、基本ノードクラス１０２ｃを有する。記憶部１０２は、例えば、ＲＯＭ（Ｒｅａｄ  Ｏｎｌｙ  Ｍｅｍｏｒｙ）、ＲＡＭ（Ｒａｎｄｏｍ  Ａｃｃｅｓｓ  Ｍｅｍｏｒｙ）、ディスクなどである。基本ノードクラス１０２ｃは、スレッドを実現するための基本クラスであり、ノードと、ノードに関するデータと、を有する。この基本ノードクラス１０２ｃが継承されると、具体的なノードが実現できる。
【００１７】
同期クラス１０２ａは、関係づけられた複数のスレッドの同期をとる同期手段である。同期クラス１０２ａは、同期条件を有し、あるスレッドが他のスレッドと同期をとるための関数ｓｙｎｃ（）を有する。関数ｓｙｎｃ（）が呼ばれると、同期条件の充足を判定する。同期条件とは、例えば、データ転送が破綻しない条件である。同期条件が充足していなければ、関数ｓｙｎｃ（）の中で、実行をスレッドに返す。つまり、関数ｓｙｎｃ（）から抜けない。同期条件が充足していれば、関数ｓｙｎｃ（）を抜けて、そのスレッドの処理を継続する。つまり、すぐに関数ｓｙｎｃ（）から抜ける。さらに、関数ｓｙｎｃ（）の中で、止まっている他のスレッドのうち、同期条件を満たすものがあれば、そのスレッドを起こす。つまり、前記同期条件が整うまで、関数から抜けるタイミングを遅延させる。これにより、上流スレッド（上流ノード）は下流スレッド（下流ノード）に起動をかけ、その起動は、同時期条件を満たしたタイミングで下流スレッドに伝搬したのと同等の効果がある。
【００１８】
同期ポートクラス１０２ｂは、同期クラス１０２ａのインスタンスである、同期オブジェクトと、基本ノードクラスの継承クラスのインスタンスである、ノードオブジェクトをつなぐための部品である。
【００１９】
つぎに、図１Ｂの１００に、設計支援装置のフローを示す。この装置では、対話的に、ノードクラスの具体化１１０と、プログラムコード１０４を作成する。プログラムコード１０４は、複数スレッドの連携を定義した記述（ここでは、データフロー記述）である。この記述をする際に、動作可能な部品である、部品１０２ａｂｃを使っているので、コンパイル（１１２）可能である。プログラムコード１０４を、コンパイル（１１２）すると、実行形式１０５を得ることができる。これを実行すれば、開発者が定義した、複数スレッドが連携した挙動が得られる。したがって、設計支援装置１００全体を見ると、本質的には、複数スレッドの連携（データフロー）に関する定義と、同期方法の選択（具体的には、同期クラスの選択）と、ノードの詳細動作記述（ノードクラス）を入力して、並列動作用プログラムを生成する装置、となっている。
【００２０】
図１Ｂでは、並列動作用のプログラムコード１０５を、コンパイル１１２によって生成するとしたが、インタプリタ―で動作するものであってもよい。いずれにせよ、複数のスレッドを並列に動作させる並列動作用のソフトウェアが簡単に得られる。
【００２１】
つぎに、図１Ｃに、デバッグ用に拡張した設計支援装置のフローを示す。本発明では、プログラムコード１０４を生成し、実際に、複数スレッドが、同期条件を充たしつつ、並列動作する、実行形式１０５が生成される。したがって、部品の一部に、重要な出来事を出力する機能を埋め込んでおけば、実行履歴１０６を生成することができる。実行履歴１０６を可視化すると、各スレッドの動作状況がわかるデータ、ガントチャート１０７を表示できる。
【００２２】
実行環境１１３としては、色々な形態が考えられ、例えば、実機、シミュレーション環境、コンピュータなどが挙げられる。実機とは、開発対象のシステムである。実機の場合には、出力データを取り出す方法が必要になる。ただし、標準出力は取り出せる場合が多いので、ここでは、標準出力として、実行履歴を出力する方法を示す。ただし、この方法に限るものではない。シミュレーション環境も実機と同様である。コンピュータを利用する場合というのは、プログラムコード１０４を、コンピュータ上で実行できるようにコンパイルして、実行することをいう。本実施の形態では、スレッドプログラミングを用いた実施例を示すが、コンピュータ上のＯＳがスレッドプログラミングに対応していれば、実行可能である。もちろん、コプロセッサとのやり取りはそのままでは実現できないので、そういった機能が含まれる場合には、対応が必要であるが、複数スレッドの連携動作の再現は可能である。ここでの連携動作とは、データフロー動作である。
【００２３】
したがって、本実施の形態では、実機でのデバッグにも有益であり、仕様検討において複数スレッドの連携動作をコンピュータ上で実行したい、といった用途にも、有益である。また、仕様検討から実機デバッグまで、同一の複数スレッドの連携制御を利用することも可能である。このように利用すれば、主要な部分が同一なので、比較検討が容易になる。
【００２４】
本実施の形態によれば、並列動作用のソフトウェアの作成の容易化を図ることができる。複数スレッドの連携制御に適した手段を提供しているので、ソフトウェア開発コストの削減を図かることができる。連携制御とは、例えば、データフロー制御である。ソフトウェア内で複数スレッドの連携動作が実現されるので、実機上でも複数スレッドの連携が動作することになり、実機におけるデバッグの容易化を図ることができる。連携動作とは、例えば、データフロー動作である。
【００２５】
最終的なソフトウェアと同じ、複数スレッドの連携制御を、コンピュータ上で実行し、直観的に理解することができる。そして、抽象的なシミュレーションとして仕様検討に利用できるので、複数スレッドの連携制御の仕様検討にかかる工数の削減を図かることができる。このため、仕様検討から実機デバッグまでを、同一の、複数スレッドの連携制御をもつ、ソフトウェアで実行できる。そして、開発コスト削減と、結果の比較分析と、の容易化を図ることができる。以上のように、ソフトウェア開発の様々な面で、ソフトウェアの作成の容易化を図ることができる。
【００２６】
スレッドの機能は、コプロセッサで実現されていてもよいし、スレッドの中から呼ばれるソフトウェアで実現されていてもよい。つまり、スレッドではコプロセッサの制御のみを行う。このため、機能がコプロセッサで実装されていても、ソフトウェアで実装されていても、混在していても、複数スレッドの連携制御が可能なのである。また、本実施例でいう、コプロセッサとは、メインのＣＰＵを補助する回路全般をさしている。一般には、ＧＰＵ（Ｇｒａｐｈｉｃｓ  Ｐｒｏｃｅｓｓｉｎｇ  Ｕｎｉｔ）のような汎用的なものをさすことが多いが、ここでは、ＪＰＥＧコーデック回路などのように特定の処理を行う回路もさす。
【００２７】
つぎに、従来との比較をすることにより、どのように、開発者のイメージに近いのか、を示しておきたい。図２〜図４に、従来のソフトウェア開発フローや従来と本発明との違いを示す。以降の説明では、複数コプロセッサの連携動作を実現する並列動作用のプログラムコードである実行形式１０５の例を示す。
【００２８】
図２は、ソフトウェア開発フローの一例を示す説明図である。まず、図２（１）に示すように、開発者は、所望の動作をするソフトウェアを開発するために、機能要件などのソフトウェアの仕様を決定する。機能要件はいくつかのスレッドなどの処理に分けられる。スレッドは、例えば、コプロセッサに対応付ける。スレッドを組み合わせて、一連のソフトウェアの処理が実現される。スレッドを組み合わせるためには、処理間の関係を定義しないといけない。処理間の関係とは、例えばスレッドＡがスレッドＢにデータを送るというようなスレッド間の依存関係である。そこで、図２（２）に示すように、例えば、開発者は、仕様に基づいて、スレッド間のデータ転送関係が定義されたデータフローなどを作成する。データフローにおいて、例えば、スレッドＡはコプロセッサＣ０に対応付けられ、スレッドＢはコプロセッサＣ２に対応付けられ、スレッドＣはコプロセッサＣ１に対応付けられ、スレッドＤはコプロセッサＣ３に対応付けられる。
【００２９】
そして、開発者は、データの受け渡しが正しくできる制御を考える。制御されるコプロセッサは、例えば、休止状態から起動、動作状態に遷移、処理、処理終了後の割り込みを上げる動作、休止状態に戻るという一連の動作を行う。
【００３０】
通例、処理の中でデータが生成される。データを正しく受け渡すためには、なんらかの制御が必要になる。例えば、２つのコプロセッサＡ，Ｂがあって、Ａが一連の処理結果データＤを生成し、ＢはＤを入力として一連の処理を実行する、という場合がある。これは、一連の処理を単位として、パイプラインが構成していることに他ならない。このような構造をタスクパイプラインと呼ぶ。一般的なパイプラインは、前段の処理と後段の処理の間にフリップフロップをおくことで、データの受け渡しをしている。フリップフロップは、概念的には、２個のラッチが縦続された構成になっている。前段のラッチは、前段の処理が専有的に利用できる。後段のラッチは、後段の処理に、後段の処理が利用するデータを、１サイクル期間、安定的に供給する。クロックエッジが入ったタイミングで、前段ラッチの値は、後段のラッチにコピーされる。このため、フリップフロップの前段の処理と後段の処理を独立的に考えて設計しても、データが正しく受け渡される。
【００３１】
タスクパイプラインにおいても、通常のパイプラインと同様に、前段の処理と後段の処理を独立的に扱えるようにしたい。このためには、データを正しく受け渡すしくみが必要である。これを実現する方法として、ダブルバッファや、リングバッファがある。ダブルバッファとは、前段の処理から後段の処理に受け渡す最大データサイズよりも大きいメモリ領域を２個用意したメモリのことである。ここでは、各々のメモリ領域を、Ａ面、Ｂ面と呼ぶことにする。前段の処理は、処理結果をＡ面に書く。後段の処理は必要データがないので休んでいる。前段の処理が一連の処理を終えると、Ａ面に、後段の処理が必要なデータが存在することになる。
【００３２】
そこで、システムは、前段の処理の終了を検出して、前段の処理と後段の処理を起動する。Ａ面には後段の処理が必要なデータがあるので、前段の処理は、処理結果をＢ面に書くようにする。つぎに、システムは、前段の処理の終了と後段の処理の終了とを検出して、前段の処理と後段の処理を起動する。この時、前段はＡ面に、後段はＢ面に、アクセスするようにする。このように入れ替えれば、後段の処理が必要なデータを前段の処理が壊してしまうことが起きない。つまり、正しいデータの受け渡しが可能になる。リングバッファとは、ダブルバッファのデータ領域数が２個だったのを、Ｎ個に拡張したものである。本実施例では、説明の簡単化のため、ダブルバッファの場合のみを取り上げる。
【００３３】
以上より、タスクパイプラインでは、パイプラインを構成する処理（タスク）が、処理中か否かが重要であることがわかる。処理中か否かを変更するイベントは、起動と、処理終了後の割り込みを上げる動作と、の２つである。そのため、図２（３）に示すように、開発者は、各スレッドの動作期間をバーで示すことができるタスクスケジューリング図を作成してレビューを行う。なお、タスクスケジューリング図は、ガントチャートとも称する。
【００３４】
その後、開発者は、図２（１）〜図２（３）などの分析作業が終了すると、実装仕様を決定する。
【００３５】
図３は、ガントチャートとシーケンス図の一例を示す説明図である。ここでは、１つのコプロセッサの動作が繰り返し実行される例である。ガントチャートでは、コプロセッサは動作中と非動作中とのいずれか一方で示される。しかし、プロセスがコプロセッサに対応付けられた場合、シーケンス図に示すように、制御用のソフトウェアを実行するＣＰＵ（Ｃｅｎｔｒａｌ  Ｐｒｏｃｅｓｓｉｎｇ  Ｕｎｉｔ）と、コプロセッサと、が協調動作することによってプロセスが実現される。ＣＰＵとコプロセッサとの間の通信は設定レジスタへの書き込みと割り込みとによって行われる。ＣＰＵがコプロセッサに動作指示する際には、ＣＰＵがコプロセッサの設定レジスタを起動状態に設定する。コプロセッサがＣＰＵに動作の終了を通知する際には、コプロセッサがＣＰＵに割り込み信号を送る。
【００３６】
図３に示すように、コプロセッサが１つであれば、コプロセッサを制御する制御用のソフトウェアは単純である。また、同様に、制御対象となるスレッドが１つであれば、制御用のソフトウェアは単純である。しかし、スレッドが複数ある場合やコプロセッサが複数ある場合、コプロセッサ間の制御が行われる。図２（３）に示したように、例えば、Ａが終わった後に、Ａ，Ｂ，Ｃをスタートさせるなどがある。スレッドが複数ある場合やコプロセッサが複数ある場合、制御用のソフトウェアは複雑となる。例えば、全体を１つの状態としてとらえて、割り込みなどで状態遷移させ、各々の状態で、所定の設定を行うようなＦＳＭ（Ｆｉｎｉｔｅ  Ｓｔａｔｅ  Ｍａｃｈｉｎｅ）を作成しなければならない。
【００３７】
そのため、制御対象が複数ある制御用ソフトウェアには以下（ａ）〜（ｃ）のような問題点がある。
（ａ）可読性：悪い
（ｂ）記述量：多い
（ｃ）デバック：高コスト
【００３８】
そこで、本実施の形態では、制御対象が複数ある場合における並列動作用のソフトウェアの開発の効率の向上を図る。
【００３９】
上述したように、タスクパイプラインの場合、データの流れと、データ受け渡しが正しく行える制御が重要である。この制御を実現するためには、複数スレッドを連携させる仕様を作ることと、その使用を実装することが困難である。このため、開発者が、機能を考えるうえで、イメージするものが入力となるような設計環境があれば、格段に生産性が向上すると推測できる。また、図２によると、開発者のイメージは、図１Ａの１０１のようなものであると推測できる。そこで、データフロー（複数スレッドの連携）を入力とする、データ受け渡しが正しく行えることが保証されることを特徴とした、設計支援システムを考案することを目的とする。
【００４０】
さらに、デバッグの場合、ソフトウェア自体が、データフロー（複数スレッドの連携）にそった動作をしているほうがわかりやすいことが推定される。従来の方法で、デバッグをする場合、開発者が、状態と、割り込みに関する情報などを使って、解析しなければならないと推測できる。この推測作業は、開発者に負荷がかかる作業である。このような解析をしなくてよくする方法として、ソフトウェア自体が、データフロー（複数スレッドの連携の１つ）として、動作すれば簡単になる。このようにして、ソフトウェアの上では、仮想的なコプロセッサが連携して、動作している状態になる。このような理由から、ソフトウェア上で、複数スレッドが連携するソフトウェアが生成する方法は、デバッグの面からも好ましいと推測される。
【００４１】
以上より、複数スレッドの連携を入力とし、実行時においても、複数スレッドの同期条件に合わせて、動作する、ソフトウェア（プログラムコード１０５）を生成するしくみを考案することにした。このしくみから、使用方法を見直すと、スレッドの機能は、コプロセッサで実現する、または、ソフトウェア（スレッド自体）で実現する、の２通りがあることになる。以下、コプロセッサの場合を説明する。最後に、ソフトウェアの場合について、説明する。
【００４２】
図４は、本実施の形態と従来技術との簡単なフローによる処理の比較例を示す説明図である。従来技術では、実装されたソースプログラムがコンパイルされてＣＰＵが実行可能なバイナリが生成される。そして、従来技術では、生成されたバイナリがＣＰＵにロードされる。
【００４３】
本実施の形態では、複数スレッドの連携（例えば、データフロー）を部品１０２ａｂｃ（図中では「本発明ライブラリ」）で記述したプログラムコード１０４を入力とし、入力したプログラムコード１０４と、コンパイル環境に含まれる、部品１０２ａｂｃ（図中では「本発明ライブラリ」）とを組み合わせて、コンパイルする。これにより、実行形式１０５が生成される。そして、生成されたバイナリがＣＰＵにロードされる。これにより、図中ＣＰＵで、複数スレッドの連携動作が実現される。スレッドにコプロセッサＣ０〜Ｃ３が含まれている時には、コプロセッサもスレッドとして、適切に制御される。スレッドにコプロセッサＣ０〜Ｃ３が含まれている時とは、具体的に、あるスレッドに、あるコプロセッサを制御する記述がなされている時である。
【００４４】
（設計支援装置１００のハードウェア構成例）
図５は、設計支援装置のハードウェア構成例を示すブロック図である。図５において、設計支援装置１００は、ＣＰＵ５０１と、ＲＯＭ５０２と、ＲＡＭ５０３と、ディスクドライブ５０４と、ディスク５０５と、を有する。設計支援装置１００は、Ｉ／Ｆ（Ｉｎｔｅｒ／Ｆａｃｅ）５０６と、キーボード５０７と、マウス５０８と、ディスプレイ５０９と、を有する。また、ＣＰＵ５０１と、ＲＯＭ５０２と、ＲＡＭ５０３と、ディスクドライブ５０４と、Ｉ／Ｆ（Ｉｎｔｅｒ／Ｆａｃｅ）５０６と、キーボード５０７と、マウス５０８と、ディスプレイ５０９とは、バス５００によってそれぞれ接続される。
【００４５】
ここで、ＣＰＵ５０１は、設計支援装置１００の全体の制御を司る。ＲＯＭ５０２は、ブートプログラムなどのプログラムを記憶する。ＲＡＭ５０３は、ＣＰＵ５０１のワークエリアとして使用される。ディスクドライブ５０４は、ＣＰＵ５０１の制御にしたがってディスク５０５に対するデータのリード／ライトを制御する。ディスク５０５は、ディスクドライブ５０４の制御で書き込まれたデータを記憶する。ディスク５０５としては、磁気ディスク、光ディスクなどが挙げられる。
【００４６】
Ｉ／Ｆ５０６は、通信回線を通じてＬＡＮ（Ｌｏｃａｌ  Ａｒｅａ  Ｎｅｔｗｏｒｋ）、ＷＡＮ（Ｗｉｄｅ  Ａｒｅａ  Ｎｅｔｗｏｒｋ）、インターネットなどのネットワーク５１０に接続され、このネットワーク５１０を介して他の装置に接続される。そして、Ｉ／Ｆ５０６は、ネットワーク５１０と内部のインターフェースを司り、外部装置からのデータの入出力を制御する。Ｉ／Ｆ５０６には、例えばモデムやＬＡＮアダプタなどを採用することができる。
【００４７】
キーボード５０７やマウス５０８は、開発者などの利用者の操作により、各種データの入力を行うインターフェースである。ディスプレイ５０９は、ＣＰＵ５０１の指示により、データを出力するインターフェースである。
【００４８】
また、図示を省略するが、設計支援装置１００には、カメラから画像や動画を取り込む入力装置やマイクから音声を取り込む入力装置が設けられていてもよい。また、図示を省略するが、設計支援装置１００には、プリンタなどの出力装置が設けられていてもよい。
【００４９】
また、本実施の形態では、設計支援装置１００のハードウェア構成として、パーソナル・コンピュータを例に挙げているが、これに限らず、サーバなどであってもよい。設計支援装置１００がサーバである場合、設計支援装置１００と利用者の操作可能な装置とがネットワーク５１０を介して接続されてもよい。
【００５０】
（設計支援装置１００の機能的構成例）
図６は、設計支援装置の機能的構成例を示すブロック図である。設計支援装置１００は、記憶部１０２と、第１生成部６０１と、実行部６０２と、第２生成部６０３と、表示部６０４と、を有する。記憶部１０２は、例えば、ＲＯＭ５０２、ＲＡＭ５０３、ディスク５０５などの記憶装置によって実現される。また、記憶部１０２は、Ｉ／Ｆ５０６を介してアクセス可能な他の装置のＲＡＭ、ＲＯＭ、ディスクなどであってもよい。
【００５１】
第１生成部６０１から表示部６０４までの制御部の処理は、例えば、図５に示すＣＰＵ５０１がアクセス可能なＲＯＭ５０２、ＲＡＭ５０３、ディスク５０５などの記憶装置に記憶されたプログラムにコーディングされている。そして、ＣＰＵ５０１が記憶装置から該プログラムを読み出して、プログラムにコーディングされている処理を実行する。これにより、制御部の処理が実現される。また、制御部の処理結果は、例えば、ＲＯＭ５０２、ＲＡＭ５０３、ディスク５０５などの記憶装置に記憶される。
【００５２】
まず、記憶部１０２には、同期クラス１０２ａと、基本ノードクラス１０２ｃが記憶されてある。同期クラス１０２ａは、同期クラスを示す記述情報である。同期クラスは、このクラスのインスタンスである同期オブジェクトに接続されるノードから同期を求める依頼（後述ｓｙｎｃ（））を調停する処理であって、例えば、ノード間のデータ転送で用いられるバッファ構造に合わせた制御を実現する。この場合の同期とは、問い合わせてきたノードの処理が先に進んでも、バッファ上のデータが破壊されない、ことを指す。例えば、ダブルバッファの場合、同期オブジェクトに接続されたノードオブジェクトがすべて、同期オブジェクトに同期を依頼してきた（ｓｙｎｃ（）をコールしている）時、任意のノードオブジェクトは処理を先に進めても、ダブルバッファは破綻しない。このように、同期クラスは、このインスタンスである、同期オブジェクトに対する、同期を求めるメッセージを利用して、同期条件（ここでは、バッファが破たんしない条件）が整わない間、ノードの実行が先に進まないように制御するしくみを提供している。同期クラスと同期オブジェクトについては、図１２〜図１４を用いて後述する。また、ここでは、同期条件は、バッファが破たんしないことだったが、同期条件は、これに限らない。
【００５３】
基本ノードクラス１０２ｃは、ノードクラスの基本クラスを示す記述情報である。基本ノードクラスを継承してノードクラスを作成し、作成したノードクラスがインスタンスされると、ノードオブジェクトとなる。ノードクラスには、スレッドにするメンバー関数ｒｕｎ（）がある。ｒｕｎ（）に、このノードでやるべき処理を書く。ｒｕｎ（）はスレッドとして、実行される。このため、本実施例では、ノードのことを文脈によってはスレッドとよんでいる場合がある。ノードクラスとノードオブジェクトについては、図９〜図１１を用いて後述する。
【００５４】
つぎに、第１生成部６０１は、プログラムコード１０４を取得する。プログラムコード１０４には、ノードオブジェクトと同期オブジェクトを所定の方法で接続したコードが含まれている。ノードオブジェクトは、ｒｕｎ（）の中で、同期したい箇所で、同期オブジェクトのメンバー関数ｓｙｎｃ（）が呼ばれる。より具体的には、ｒｕｎ（）の中で、同期ポートオブジェクトを介してメンバー関数ｓｙｎｃ（）が呼ばれる。
【００５５】
同期オブジェクトは、ｓｙｎｃ（）が呼ばれると、同期条件が成り立つかを判定する。同期条件が成り立てば、同期条件が成り立つのを待っているスレッドを起こす。より具体的には、スレッドカーネルに、他のスレッドを起こす信号を送る。後述する図１３の例はこのようになっている。後述する図２９Ｂでは、ｓｙｎｃ（）に到達した順にｓｙｎｃ（）から抜けるようにするため、同期条件が成り立ったスレッドは最後にｓｙｎｃ（）を抜けるように設計されてある。これにより、ｓｙｎｃ（）で、同期条件が成り立たず、実行が停止していたスレッドは、ｓｙｎｃ（）関数を抜けて、先に進む。同期条件が成り立たない場合には、ｓｙｎｃ（）の中で、同期条件が成り立った時に送られてくる信号を待つ。これにより、ｓｙｎｃ（）を呼び出したスレッドは、実行待ちになる。ｒｕｎ（）では、逐次的に処理を記述するが、同期オブジェクトのｓｙｎｃ（）をコールした段階で、同期オブジェクトが、同期条件が成り立ったと判定するまで、ｓｙｎｃ（）から抜けないように動作する。そのため、ｒｕｎ（）では、同期条件が成り立つまで、先の処理には進めない。したがって、同期条件を常に満たしつつ、複数スレッドの連携動作をさせることができるのである。プログラムコード１０４については、図１５を用いて後述する。
【００５６】
図７は、データフロー例を示す説明図である。データフロー７００は、ノードと、ノード間のデータの入出力関係を示す矢印と、を含む有向グラフである。データフロー７００は、ノードｓｏｕｒｃｅと、ノードＰａｌａ［０］〜Ｐａｌａ［３］と、ノードｓｏｌｏと、ノードｓｉｎｋと、を有する。
【００５７】
ノードＰａｌａ［０］〜Ｐａｌａ［３］は、それぞれノードｓｏｕｒｃｅからデータを受け付ける。そして、ノードＰａｌａ［０］〜Ｐａｌａ［３］は、それぞれノードｓｏｌｏにデータを出力する。ノードｓｏｌｏは、例えば、ノードＰａｌａ［０］〜Ｐａｌａ［３］のそれぞれからデータを受け付ける。そして、ノードｓｏｌｏは、ノードｓｉｎｋにデータを出力する。
【００５８】
図８は、データフローのモデル化例を示す説明図である。本実施の形態では、２つのオブジェクトによってデータフロー７００をモデル化し、モデル化されたデータフロー７００を入力とする。ノードは、ノードオブジェクトによってモデル化される。そして、矢印間の依存関係は、同期オブジェクトによってモデル化される。これにより、同期オブジェクトが定める同期条件を充たすべきであることを定義したことになる。このようにして、開発者などの利用者は、データフロー７００が示す入出力関係を同期オブジェクトとノードオブジェクトによって表したプログラムコード１０４を作成する。
【００５９】
図９は、ノードオブジェクト例を示す説明図である。本実施の形態では、ノードオブジェクトは、例えば、コプロセッサの制御を表すオブジェクトである。そのため、ノードオブジェクトは、ＩＮ待ち、設定、割り込み待ち、ＯＵＴ待ちの４つの処理を順に行う。
【００６０】
ＩＮ待ちは、上流ノードからの起動を待つ処理である。上流ノードからの起動を待つと書いたが、具体的には、上流ノードと接続している同期オブジェクトのｓｙｎｃ（）から、復帰するのを待つ。設定は、コプロセッサへの設定を行う処理である。割り込み待ちは、コプロセッサからの処理の終了を通知するための割り込みを待つ処理である。ＯＵＴ待ちは、下流ノードへの起動を指示する処理である。下流ノードへの起動指示を待つ処理と書いたが、具体的には、下流ノードとつながっている同期オブジェクトのｓｙｎｃ（）から復帰するのを待つことを指す。このように、実際には、同期オブジェクトのｓｙｎｃ（）関数で、同期クラスが定める同期条件が成り立つまで遅延する。これは、観念的には、適切なタイミングで、上流ノードから下流ノードに起動を送る機能に相当する。このため、以下の説明でも、観念的な説明をする場合には、同期の代わりに、起動とも呼ぶ。
【００６１】
図１０は、ノードクラス例を示す説明図である。本実施の形態では、ｐｔｈｒｅａｄプログラミングを利用した例を示す。信号待ちによる同期を実現するためにノードごとに制御用のスレッドを用意する。そのため、ノードクラスは、ｒｕｎ（）を有する。実際には、後述のとおり、図２４のｃｒｅａｔｅ（）で、自分自身へのポインタを、クラス関数ｒｕｎ＿ｂａｓｅに渡して、これをスレッドとして実行、ｒｕｎ＿ｂａｓｅの中で、引数でもらったポインタが指すオブジェクトのｒｕｎ関数を呼ぶ。これは、単に、ｐｔｈｒｅａｄの仕様に合わせるためのものなので、事実上、メンバー関数ｒｕｎ（）をスレッドとして実行している。すべてのノードのｒｕｎ（）は、最初に、スレッド関数として呼び出される。具体的には、図３３の／／ｃｒｅａｔｅの後の記述のように、すべてのノードに対して、ｃｒｅａｔｅ（）を呼ぶ。つぎに、すべてのスレッドが終わったのを検出する。具体的には、／／ｊｏｉｎの後の記述のように、すべてのノードに対して、ｊｏｉｎ（）を呼ぶ。
【００６２】
ｒｕｎ（）は、上流ノードからの起動を待つ処理と、ｓｅｔｕｐ（）と、コプロセッサの終了を待つ処理と、下流ノードに起動をかける処理と、を有する。下流ノードに起動をかける処理が終了した後は、上流ノードからの起動を待つ。
【００６３】
図１０に示すように、起動をかける処理と起動を待つ処理との間の期間は、おおむね、コプロセッサの休止期間である。また、ｓｅｔｕｐ（）やコプロセッサの終了を待つ処理の期間は、おおむね、コプロセッサの動作期間である。
【００６４】
ｓｅｔｕｐ（）では、コプロセッサへの設定を行う。コプロセッサの終了を待つ処理では、コプロセッサからの終了を示す割り込みを待つ。下流ノードに起動をかける処理では、前述のとおり、（下流側の同期オブジェクトの）ｓｙｎｃ（）から抜けるのを待つ。上流ノードからの起動を待つ処理に移行する。上流ノードからの起動を待つ処理は、前述のとおり、（上流側の同期オブジェクトの）ｓｙｎｃ（）から抜けるのを待つ。
【００６５】
図１１は、ノードクラスの詳細例を示す説明図である。記述情報１１００は、ノードクラスの記述例を示す。ノードクラスでは、図１０においても説明したように、ｒｕｎ（）が定義されてある。点線枠内は、下流ノードへの起動をかける処理から上流ノードからの起動を待つ処理へのループ部分に相当する。
【００６６】
ｐｏｒｔ＿ｉｎ．ｓｙｎｃ（）は、上流ノードからの起動指示を待つための同期処理である。ｐｏｒｔ＿ｉｎは、同期ＩＮポートオブジェクトである。前述のとおり、本実施例では、同期ポートオブジェクトを介して、同期オブジェクトにアクセスする例を示している。実線枠内は、図１０で説明したｓｅｔｕｐ（）に相当する部分であり、コプロセッサへの設定を行う処理に相当する。図１０の例では、ｓｅｔｕｐ（）は、設定の代わりに、上流ノードからのデータを印字し、下流ノードにデータを送信する処理を行う。
【００６７】
ｇｕａｒｄ（）は、コプロセッサの終了を待つ処理であり、コプロセッサと同期を行う処理である（コプロセッサとｇｕａｒｄ（）の関係については図２５のとおり）。ｐｏｒｔ＿ｏｕｔ．ｓｙｎｃ（）は、下流ノードへ起動をかける処理であり、下流ノードと同期する処理である。ｐｏｒｔ＿ｏｕｔは、同期ＯＵＴポートオブジェクトである。前述のとおり、本実施例では、同期ポートオブジェクトを介して、同期オブジェクトにアクセスする例を示している。
【００６８】
図１２は、同期オブジェクト例を示す説明図である。同期オブジェクトは、ノード間で、同期をとるソフトウェアである。概念的には、上流ノードから下流ノードへの起動の通知を伝搬する処理を行い、同期条件が揃うまで起動の通知を遅延させる、処理をしている。正確には、前述のとおり、同期をとるために、同期オブジェクトに関係するノードは、同期オブジェクトのメンバー関数ｓｙｎｃ（）を呼ぶが、同期オブジェクトは、条件が整うまで、ｓｙｎｃ（）関数からの復帰が遅延される。
【００６９】
同期条件は、例えば、同期オブジェクトに関係するすべてのノードオブジェクトが同期オブジェクトに対してＯＵＴ待ち、またはＩＮ待ちになっていることである。ダブルバッファによるデータ転送で、正常なデータ転送が行えるための条件である。このタイミングでバッファを入れ替えれば、必要なデータを破壊することは起きない。
【００７０】
図１３は、同期クラスｓｙｎｃ＿ｔのメンバー関数ｓｙｎｃ（）を示す説明図である。記述情報１３００に、ｓｙｎｃ（）の記述例を示す。ｓｙｎｃ＿ｔには、ｓｙｎｃ（）に入ったノードの数を記憶するメンバー変数ｍ＿ｒｅａｃｈ＿ｎｕｍがある。この変数は、ｓｙｎｃ＿ｔのコンストラクタで０が代入される。また、ここでは図示していないが、ｓｙｎｃ＿ｔには、メンバー変数ｍ＿ｐｏｉｎｔ＿ｎｕｍがある。プログラムコード１０４で、複数スレッドの連携（例えば、データフロー）を記述した部分が実行されると、接続されるノードの数を計数して、ｍ＿ｐｏｉｎｔ＿ｎｕｍに格納する。
【００７１】
ｓｙｎｃ（）は、コールされると、ｍ＿ｒｅａｃｈ＿ｎｕｍを１増やす。ｍ＿ｒｅａｃｈ＿ｎｕｍがｍ＿ｐｏｉｎｔ＿ｎｕｍよりも小さかったら、ｍ＿ｃｏｎｄを待つ。ｍ＿ｒｅａｃｈ＿ｎｕｍがｍ＿ｐｏｉｎｔ＿ｎｕｍと等しかったら、すべてのノードがｓｙｎｃ（）に入ったことになるので、ｍ＿ｒｅａｃｈ＿ｎｕｍをクリアして、ｍ＿ｃｏｎｄをブロードキャストする。これにより、ｍ＿ｃｏｎｄを待っていたスレッドは、待ち状態を終了する。したがって、順次、ｓｙｎｃ（）を抜ける。このようにして、すべてのノードが、ｓｙｎｃ（）に入るまで、ｓｙｎｃ（）から抜けないようにすることができるのである。
【００７２】
図１４は、同期クラス例を示す説明図である。記述情報１４００には、ｓｙｎｃ＿ｔが記述される。図１３のｓｙｎｃ（）は、ｓｙｎｃ＿ｔのメンバー関数である。ここでは、上流ノードと下流ノードの間で、パラメータ転送ができる記述例について、説明する。パラメータとは、例えば、一連の処理の終了フラグなどである。
【００７３】
実施例の同期オブジェクトは、同期条件が、ダブルバッファで正しくデータ転送が行えることなので、ノード間のパラメータ転送も、ダブルバッファにすればよい。ｓｙｎｃ＿ｔがノード中のＯＵＴポートに接続されるごとに、ａｄｄ＿ｏｕｔ（）がコールされ、同期オブジェクトの入力側ノード数分のダブルバッファが用意される。ｓｙｎｃ（）で同期が取れると、ｕｐｄａｔｅ＿ｖａｌｕｅ（）が呼ばれる。これにより、上流ノード用バッファと、下流ノード用バッファが入れ替わる。このようにして、ノード間でのパラメータのやり取りを実現する。なお、ｕｐｄａｔｅ＿ｖａｌｕｅ（）が呼ばれるタイミングは、ダブルバッファを安全に切り替えられるタイミングである。
【００７４】
図１５は、データフローの記述例を示す説明図である。記述情報１５００は、データフロー７００を同期オブジェクトとノードオブジェクトとによって記述したプログラムコード１０４である。上述したように、データフロー７００のモデル化については、開発者によって行われる。本実施の形態では、開発者が、ノードオブジェクトと、同期オブジェクトと、を使ってデータフロー７００を定義する。記述情報１５００には、ノードの宣言、同期の宣言、ノードと同期の接続、とが記述される。
【００７５】
つぎに、第１生成部６０１は、部品１０２ａｂｃと、ノードクラス１０３と、プログラムコード１０４と、を組み合わせた並列動作用のプログラムコード１０５を生成する。第１生成部６０１は、コンパイルを行うことによって実行形式のバイナリコードを生成してもよい。ここでは、並列動作用のプログラムコード１０５は、コンパイル後のバイナリコードとして説明する。
【００７６】
図１６は、実行例を示す説明図である。コプロセッサに対する設定部分に対して標準出力を記載した場合における実行結果例である。
【００７７】
ノードオブジェクトと、同期オブジェクトと、によれば、開発者が、データフロー７００を直感的にコーディングすることができる。また、ノードオブジェクトは並列に動作することができる。コプロセッサを制御するプログラムはノードクラスの中に記述される。ノードオブジェクトが割り込みを受理できる。
【００７８】
ここで、同期オブジェクトによる動作の詳細例について、図１７から図１９を用いて説明する。本実施の形態では、ダブルバッファでデータのやり取りを実現する場合の同期クラスを例に挙げているが、これに限らず、リングバッファに対応した同期クラスを定義してもよい。また、本実施の形態は、より本質的には、同期条件を示すクラスを導入して、そのクラスとスレッドの関係を与えることにより、連携させるしくみである。したがって、上述した例は、コプロセッサの連携の制御であったため、連携のさせ方がデータフローで、同期条件がバッファに関するものである。したがって、一般的には、連携のさせ方は、データフローに限らないし、同期条件は、バッファに関する条件に限らない。
【００７９】
図１７は、同期オブジェクトの利用例を示す説明図である。ここでは、ノードオブジェクトは、Ｎ０〜Ｎ３まである。同期オブジェクトＳｙｎｃ＿０は、ノードオブジェクトＮ０とノードオブジェクトＮ１からの起動指示を同期させてノードオブジェクトＮ２とノードオブジェクトＮ３に伝搬させる。換言すると、Ｎ０〜Ｎ３のすべてが、Ｓｙｎｃ＿０のメンバー関数ｓｙｎｃ（）に入っている状態を検出し、順次、ｓｙｎｃ（）から戻る。
【００８０】
図１８Ａ〜図１８Ｅは、同期オブジェクトの動作例を示す説明図である。図１９は、同期処理のシーケンス例を示す説明図である。ノードＮ０〜ノードＮ３は並列に動作するスレッドとする。ここでは、図１９に示すように、２回同期した例を示す。通例、ｇｕａｒｄ（）ではコプロセッサの終了を知らせる割り込みを待つため、このタイミングで、スレッドが実行待ちになる。したがって、スレッドカーネルに制御が戻る。しかし、ここでは、動作の説明の簡単化のため、ｇｕａｒｄ（）で割り込み待ちをしない例を示す。このようにしても、同期オブジェクトの動作を説明するうえで、差し支えはない。なお、図１８Ａ〜Ｅ、図１９の同期クラスは、図１３の定義ではなく、図２９Ａ〜Ｂの定義の動作になっている。
【００８１】
図１８Ａの（Ａ）は初期状態である。図１８Ａの（Ａ）のとおり、ノードオブジェクトＮ０とノードオブジェクトＮ１とについては、ＩＮ側の同期はないが、ＯＵＴ側の同期がある。
【００８２】
また、図１８Ａの（Ａ）のとおり、ノードオブジェクトＮ２とノードオブジェクトＮ３とについては、ＩＮ側の同期があるが、ＯＵＴ側の同期がない。
【００８３】
図１８Ａの（Ｂ）では、ノードオブジェクトＮ０は、ｌｏｃｋ（）、ｓｅｔｕｐ（）、ｇｕａｒｄ（）、ｕｎｌｏｃｋ（）を（１）実行する。各ノードオブジェクトのｌｏｃｋ（）、ｓｅｔｕｐ（）、ｇｕａｒｄ（）、ｕｎｌｏｃｋ（）の詳細例については、＜詳細例＞に示す。そして、ノードオブジェクトＮ０は、Ｓｙｎｃ＿０．ｓｙｎｃ（）に入る。同期条件が整っていないので、Ｓｙｎｃ＿０．ｓｙｎｃ（）の中で、（２）同期待ちに入る。
【００８４】
図１８Ｂの（Ｃ）では、ノードオブジェクトＮ１は、ｌｏｃｋ（）、ｓｅｔｕｐ（）、ｇｕａｒｄ（）、ｕｎｌｏｃｋ（）を（３）実行する。そして、ノードオブジェクトＮ１は、Ｓｙｎｃ＿０．ｓｙｎｃ（）に入る。同期条件が整っていないので、Ｓｙｎｃ＿０．ｓｙｎｃ（）の中で、（４）同期待ちに入る。
【００８５】
そして、図１８Ｂの（Ｄ）では、ノードオブジェクトＮ２が、Ｓｙｎｃ＿０．ｓｙｎｃ（）に入る。同期条件が整っていないので、Ｓｙｎｃ＿０．ｓｙｎｃ（）の中で、（５）同期待ち状態になる。つぎに、図１８Ｃの（Ｅ）では、ノードオブジェクトＮ３が、Ｓｙｎｃ＿０．ｓｙｎｃ（）に入る。ここで、同期条件が整うので、同期待ちをしている、（６）他のスレッドを起こし、ｍ＿ｒｅｌｅａｓｅ＿ｎｕｍに１を格納する。ノードオブジェクトＮ３が最後にＳｙｎｃ＿０．ｓｙｎｃ（）に入ったスレッドなので、（７）最後のスレッドを起こす信号待ち状態にする。他のスレッドを起こすとは、スレッドカーネルに同期信号を送信させることである。
【００８６】
そして、図１８Ｃの（Ｆ）では、スレッドカーネルが（８）ノードオブジェクトＮ０を起こす。これにより、ノードオブジェクトＮ０は、同期待ち状態を抜ける。ｍ＿ｒｅｌｅａｓｅ＿ｎｕｍをインクリメントする。ノードオブジェクトＮ０は、ｌｏｃｋ（）、ｓｅｔｕｐ（）、ｇｕａｒｄ（）、ｕｎｌｏｃｋ（）を（９）実行する。そして、ノードオブジェクトＮ０は、Ｓｙｎｃ＿０．ｓｙｎｃ（）に入る。同期条件が整っていないので、Ｓｙｎｃ＿０．ｓｙｎｃ（）の中で、（１０）同期待ち状態になる。
【００８７】
つぎに、図１８Ｄの（Ｇ）では、スレッドカーネルが（１１）ノードオブジェクトＮ１を起こす。これにより、ノードオブジェクトＮ１は同期待ち状態を抜ける。ｍ＿ｒｅｌｅａｓｅ＿ｎｕｍをインクリメントする。そして、ノードオブジェクトＮ１は、ｌｏｃｋ（）、ｓｅｔｕｐ（）、ｇｕａｒｄ（）、ｕｎｌｏｃｋ（）を（１２）実行する。ノードオブジェクトＮ１は、Ｓｙｎｃ＿０．ｓｙｎｃ（）に入る。同期条件が整っていないので、Ｓｙｎｃ＿０．ｓｙｎｃ（）の中で、（１３）同期待ち状態になる。
【００８８】
そして、図１８Ｄの（Ｈ）では、スレッドカーネルが（１４）ノードオブジェクトＮ２を起こす。これにより、ノードオブジェクトＮ２は同期待ち状態を抜ける。ｍ＿ｒｅｌｅａｓｅ＿ｎｕｍをインクリメントする。ここで、ｍ＿ｒｅｌｅａｓｅ＿ｎｕｍがｍ＿ｐｏｉｎｔ＿ｎｕｍと一致する。つまり、１回目の同期で、最後にＳｙｎｃ＿０．ｓｙｎｃ（）に入ったスレッド以外のスレッドがすべて起きたことになる。そこで、（１５）最後のスレッドを起こすよう指示する。つぎに、ノードオブジェクトＮ２は、ｌｏｃｋ（）、ｓｅｔｕｐ（）、ｇｕａｒｄ（）、ｕｎｌｏｃｋ（）を（１６）実行する。ノードオブジェクトＮ２は、Ｓｙｎｃ＿０．ｓｙｎｃ（）に入る。ノードオブジェクトＮ２は、同期条件が整っていないので、Ｓｙｎｃ＿０．ｓｙｎｃ（）の中で、（１７）同期待ち状態になる。
【００８９】
図１８Ｅの（Ｉ）では、スレッドカーネルが、（１８）ノードオブジェクトＮ３を起こす。これにより、ノードオブジェクトＮ３は同期待ち状態を抜ける。つぎに、ノードオブジェクトＮ３は、ｌｏｃｋ（）、ｓｅｔｕｐ（）、ｇｕａｒｄ（）、ｕｎｌｏｃｋ（）を（１９）実行する。ノードオブジェクトＮ３は、が、Ｓｙｎｃ＿０．ｓｙｎｃ（）に入る。ここでは、同期条件が整うので、同期待ちをしている、（２０）他のスレッドを起こし、ｍ＿ｒｅｌｅａｓｅ＿ｎｕｍに１を格納する。ノードオブジェクトＮ３が最後にＳｙｎｃ＿０．ｓｙｎｃ（）に入ったスレッドなので、（２１）最後のスレッドを起こす信号待ち状態にする。
【００９０】
このようにして、同期オブジェクトは、同期条件が整うまで、ｓｙｎｃ（）から抜けないようにする。これは、ノードオブジェクトＮ０とノードオブジェクトＮ１からの起動指示を同期させてノードオブジェクトＮ２とノードオブジェクトＮ３とに受け渡す動作を実現していると解釈できる。以上は、ダブルバッファの場合の同期例である。同期条件は、バッファの形態によって変わる。もし、リングバッファであれば、リングバッファのバッファ数を与え、同期オブジェクトへデータを送る側のｓｙｎｃ（）では、バッファの使用数が、バッファ数―１以下であればｓｙｎｃ（）を抜け、バッファ数と同じであれば、バッファの使用数がバッファ数―１以下になるのを待つ。一方、同期オブジェクトからデータを受け取る側のｓｙｎｃ（）では、すべてのリングバッファの使用数が１以上になるのを待つ。すべてのリングバッファの使用数が１以上になったら、ｓｙｎｃ（）を抜ける。再度、ｓｙｎｃ（）に入った時、すべてのリングバッファの使用数を１減らす。このようにすれば、リングバッファにも対応できる。以上のように、プログラムコード１０５を作成し、図４「本発明」中ＣＰＵで実行させると、図１Ｂに示したフローが実現する。
【００９１】
＜ガントチャート作成例＞
つぎに、デバッグ機能を追加した、拡張フロー（図１Ｃ）を説明する。本発明では、図４のＣＰＵにロードされる実行形式１０５において、複数スレッドの連携動作（例えば、データフロー動作）そのものを実行しているといってよい。換言すれば、開発者がイメージしていたソフトウェアを、実際に動かしているとも解釈できる。イメージと実際の動作の差が小さいことになる。したがって、不具合の要因に気がつきやすく、デバッグが容易であるといってよい。さらに、開発者が不具合の要因に気がつきやすくなるためには、可視化が有効である。可視化を行うことにより、開発者は、実行形式１０５の動作を直観的に理解できる。例えば、ガントチャートによれば、制御される対象である、コプロセッサの動きを直観的に理解できる。ガントチャートは、スレッドごとに、状態変化を可視化したものなので、複数スレッドの連携動作（データフロー動作）に近い。
【００９２】
一方、従来の方法によると、開発者が、ガントチャートのようなデータを取得するためには、作成したソースをレビューしてどこに出力文を挿入すれば所望データがとれるかを検討し、再設計とソフトウェア改版をしなければならない。このように、開発者の手間がかかる。本実施の形態では、複数スレッドの連携動作（データフロー動作）をソフトウェアの中で実現しているので、部品の中に、予め、出力文を入れておけばよい。具体的には、ガントチャートを作る場合には、スレッドの実行開始と終了と、同期オブジェクトのｓｙｎｃ（）関数の前後、または、ｇｕａｒｄ（）の割り込み待ちの前後のタイミングで出力すれば、おおむね正しいガントチャートが作れるデータをそろえられる。
【００９３】
本実施の形態例における、同期クラスなどの詳細は後述する図２８Ａ〜図２８Ｂの通りである。この中には、同期クラスのインターフェースクラス、同期クラス、同期オブジェクトと接続するための同期ポートクラスがある。さらに、同期ポートクラスには、２つの継承クラス、同期ＩＮポートクラスと同期ＯＵＴポートクラスがある。同期ＩＮポートクラスや同期ＯＵＴポートクラスは、ノードオブジェクトの中にインスタンスされる。インスタンス例については、後述する図３０〜図３２に具体例を示す。
【００９４】
図１５の場合、ノードオブジェクトの中の同期ポートオブジェクトと同期オブジェクトの接続は、ｍａｉｎ（）関数の中で行われている。例えば、ｉ＿ｓｒｃ．ｐｏｒｔ＿ｏｕｔ（ｓｒｃ＿ｐａｌａ）；が、このような接続を行っている記述である。この接続では、同期ＯＵＴポートクラスｐｏｒｔ＿ｏｕｔ＿ｔの中のメンバー関数ｏｐｅｒａｔｏｒ（）が呼ばれる。この関数の中で、後述する図２８Ｂのように、同期オブジェクトのａｄｄ＿ｏｕｔ（）がコールされる。これにより、同期オブジェクトに接続されているノードオブジェクトの情報を、同期オブジェクトに渡している（本実施例では、ノード間で、パラメータを受け渡すために、同期オブジェクト内にパラメータ用のデータ記憶領域を確保するために、使われているだけである）。同期ＩＮポートクラスについても同様である。
【００９５】
後述する図２８Ａによると、同期ポートクラスで、ｓｙｎｃ（）が定義されている。したがって、同期ポートオブジェクトのｓｙｎｃ（）関数がコールされると、この同期ポートオブジェクトに接続されている同期オブジェクトのｓｙｎｃ（）がコールされる。このようにして、ノードオブジェクトと同期オブジェクトは通信している。したがって、図２１の（１）の同期ＯＵＴポートクラスの変更例のように、ｓｙｎｃ（）をオーバーライドして、この関数の中で、同期オブジェクトのｓｙｎｃ（）をコールする前後に、履歴を出力する記述を追加すれば、所望のデータが取れる。また、ｇｕａｒｄ（）に関する履歴をとる場合には、図２４の、ｐｔｈｒｅａｄ＿ｃｏｎｄ＿ｗａｉｔ（）の前後に、履歴を出力する記述を追加すればよい。
【００９６】
このようにして出力した、実行履歴データは、後述する図２０のように、コンピュータ１００により受信され、実行履歴１０６に出力される。実行履歴１０６には、スレッドの状態が変化する実行履歴が含まれている。したがって、このデータからガントチャートを作ることができる。実施例では、標準出力を利用して、実行履歴をとる場合を示したが、これ以外の方法でもよい。実行履歴データに、タイマーの値を含めて、時間情報つきにしてもよい。図１５や後述する図４２のノードオブジェクトと同期オブジェクトについての後述する図４４に示す接続関係データを使って、後述する図４５のように、依存関係を矢印によって表示してもよい。後述する図４４に示す接続関係データを落とす一方法は、記憶部１０２の中のライブラリをデータ構造出力用に変更したものを用意し、これとプログラムコード１０４をコンパイルして、接続関係出力用の実行形式を生成し、この実行形式を実行して、後述する図４４に示す接続関係データを生成する方法が考えられる。
【００９７】
以上のように、本実施の形態によれば、簡単なしくみで、実行履歴が取れるのである。なぜ簡単に取れるかというと、実行形式１０５をＣＰＵで実行すると、利用者がイメージする、つまり、開発者が見たいと考える、複数スレッドの連携動作が、ＣＰＵ上で実現されるからである。したがって、上記のように、複数スレッドの連携を実現しているしくみのしかるべき場所に履歴を出力する記述を加えさえすれば、複数スレッドの連携動作を再現できる実行履歴が得られるのである。開発者が見たいものを動作させることができるという効果がある。単純な構造で所望の機能を実現するほうが、安全性、保守性などの様々な面において向上を図ることができる。したがって、部品１０２ａｂｃの導入による、複数スレッドの連携動作を実現するしくみは、記述が容易になるだけでなく、デバッグ機能を、安全で、保守しやすい形で実現する。さらに、開発者は簡単に利用できる。ソフトウェア開発で重要な、トライアンドエラーの両面、つまり、ソフトウェアを作成することと、デバッグすることとの両面で、生産性の向上が図れる。これは、部品開発視点に立っても、部品利用視点に立っても、しくみが簡単で、利用が簡単であるため、生産性の向上が図れる。
【００９８】
つぎに、以上に説明したことを、図６の構成図にそって説明したい。ガントチャートを利用する場合には、通常の同期用コード１０２の代わりに、実行履歴を出力するように変更した（例えば、図２１のように書き換えた）部品１０２ａｂｃを使い、第１生成部６０１により、並列実行用のプログラムコード１０５を生成する。実行部６０２は、生成された並列動作用のプログラムコード１０４の実行形式１０５を実行する。この時、実行部６０２は、並列動作用のプログラムコード１０４の実行中に、実行履歴１０６を記憶部１０２に記憶させる。
【００９９】
そして、第２生成部６０３は、記憶部１０２に記憶された実行履歴１０６をもとに、スレッドごとに状態変化を図示する。表示のしかたとしては、例えば、ガントチャートやシーケンス図がある。そして、表示部６０４は、生成された図を表示する。表示部６０４は、例えば、ディスプレイ５０９に図を表示する。
【０１００】
図２０は、ガントチャートの表示例を示す説明図である。図２０には、実際に開発対象のシステム２０００（実機ともいう）に含まれるＣＰＵ２００１に並列動作用のプログラムコード１０４の実行形式１０５をロードさせた場合の例を示す。システム２０００は、例えば、ＣＰＵ２００１と、コプロセッサＣ０〜コプロセッサＣ３と、を有する。そして、ＣＰＵ２００１と、コプロセッサＣ０〜コプロセッサＣ３とはバスを介して接続される。
【０１０１】
システム２０００は、例えば、設計支援装置１００とインターフェースを介して接続される。そのため、設計支援装置１００は、ＣＰＵ２００１に並列動作用のプログラムコード１０４の実行形式１０５をロードさせることができ、実行履歴１０６を取得することができる。
【０１０２】
実行部６０２は、開発対象となるシステム２０００に含まれるＣＰＵ２００１にバイナリである並列動作用のプログラムコード１０４の実行形式１０５をロードさせ、ＣＰＵ２００１に並列動作用のプログラムコード１０４を実行させる。つぎに、設計支援装置１００は、ＣＰＵ２００１が並列動作用のプログラムコード１０４を実行中に、実行履歴データを取得して実行履歴１０６を生成する。
【０１０３】
そして、設計支援装置１００は、実行履歴１０６に基づいてガントチャート２００４を作成し、作成したガントチャート２００４を画面２００３に表示する。ガントチャート２００４は、例えば、スレッドの各々について、実行履歴２００２に基づいて、実行期間の各タイミングが、入力待ち、処理中、出力待ち、などによって分類される。
【０１０４】
そして、表示部６０４は、例えば、画面２００３をディスプレイ５０９に表示する。これにより、コプロセッサの動作状況を可視化することができる。
【０１０５】
図２１は、実行履歴を記憶するための記述例を示す説明図である。図２１（１）には、ｓｙｎｃが実行される前後で、ｓｙｎｃを実行するノードオブジェクトの名称を出力するための記述例を示す。図２１（２）には、ｒｕｎが実行される前後で、ｒｕｎを実行するノードオブジェクトの名称を出力する記述例を示す。これにより、開発対象のシステムの内部の動作を可視化することができる。
【０１０６】
また、ここでは、実際の開発対象のシステムにロードさせる例を示したが、システムをプログラミング言語などによってモデル化したシステムモデルにロードさせる場合も同様に、内部の動作を可視化することができる。また、以前にも書いた通り、実行形式にかぎらない。ＣＰＵ上で、並列動作用のプログラムコード１０４をインタプリタで処理するとしてもよい。また、ＣＰＵ上のＶＭ（Ｖｉｒｔｕａｌ  Ｍａｃｈｉｎｅ）で実行するとしてもよい。
【０１０７】
図２２は、分析作業の支援例を示す説明図である。ここでは、開発中の並列実行用のプログラムコード１０４を、コンピュータ上で実行する実行形式１０５を生成し、実行部６０２として、コンピュータを用いる利用例を示す。このようにすると、開発システム（実機ともいう）２０００で利用するプログラムコード１０４と、基本的に同じプログラムコードをコンピュータ上で実行できるようになる。実機とコンピュータで異なるものもある。具体例としては、スレッドがコプロセッサによる機能実現した場合がある。この場合、ソフトウェア上のスレッドにはコプロセッサの制御（ｓｅｔｕｐ（））と割り込みの受理（ｇｕａｒｄ（））が記述され、ソフトウェア上のスレッドでコプロセッサの制御が行われる。実際のコプロセッサが通信することにより、ソフトウェア上のスレッドのコプロセッサの制御と、実際のコプロセッサが協調して、１つのスレッドとして動作する（参考：図９、図１１）。しかし、コンピュータ上には、実際のコプロセッサはないので、このようなスレッドの実現はできない。したがって、何らかの対策が必要である。対策の１案は、コプロセッサの制御記述を空関数にして実行することである。制御記述とは、ｓｅｔｕｐ（）またはｇｕａｒｄ（）である。図９に示した設定と割り込み待ちとが行われないため、プログラムコード１０４がコプロセッサに依存させないようにすることができる。
【０１０８】
同期オブジェクトはスレッドライブラリの機能を使って、同期を実現するしくみなので、スレッドライブラリが提供されているＯＳ上のコンパイル環境であれば、コンパイル可能であり、実行できる。このようにした場合、コプロセッサの具体的な制御はしないものの、複数スレッドの連携動作（例えば、データフロー動作）は実行していることになる。このような実行は、上述した図１Ａ、図２などで示した通り、複数スレッドの連携（例えば、データフロー）であるため、開発初期時の検討をシミュレーションしていることに相当する。さらに、部品は共通であり、実機で動作させうるプログラムコード１０４を抽象化したものを、コンピュータ上で実行している。すなわち、抽象度の高いレベルから具象化した、実機で動作するプログラムコードの実行形式１０５まで、同一の制御構造（アーキテクチャ）を利用した開発が行えるということを意味する。同一のアーキテクチャを使っているので、抽象度の高いシミュレーションで得た知見は、実機におけるデバッグでも利用可能である。つまり、実機におけるデバッグまでに習熟した内容が、実機におけるデバッグで効果がでる。したがって、習熟した内容が効率的に利用される開発方法になっているといいうる。開発方法論的側面については、図４０を用いて、後述する。
【０１０９】
さらに、先に示した実行履歴データの取得は、部品１０２ａｂｃを拡張して、実現するものだった。この部分は、抽象化して、コンピュータ上で実行する場合にも利用する。したがって、実行履歴を落とすことができ、ガントチャートを出力することができる。したがって、利用者は、複数スレッドの連携動作（例えば、データフロー動作）を、直観的に、観察することができる。さらに、ｓｅｔｕｐ（）とｇｕａｒｄ（）にかかる予想時間を入れると、コプロセッサの時間負荷を考慮した動作も実現できる。簡単な実施形態としては、ｓｅｔｕｐ（）；ｇｕａｒｄ（）の代わりに、ｓｌｅｅｐ（）やｎａｎｏｓｌｅｅｐ（）をコールして、遅延させる方法がある。
【０１１０】
また、遅延を管理するスレッドを追加してもよい。例えば、シミュレーション全体の時間を管理する時計を用意しておき、スレッドごとに、状態を保持する変数と、「時間待ちで停止している」スレッドが起きるべき時間を保存する変数を用意する。状態とは、同期で停止している状態、時間待ちで停止している状態、どちらでもない状態のいずれかである。「どちらでもない」になっているスレッドが０個の時に時刻の更新を行う。「時間待ちで停止している」スレッドが、起きたい時刻をしらべて、直近の時刻まで時計を進め、進めた時刻で起きるべきスレッドを起こす。
【０１１１】
これにより、スレッド、つまり、ノードオブジェクトのｒｕｎ（）の実行が再開される。この後の実行により、同期が起きることがある。同期が起きると、「同期で停止している」スレッドが、「どちらでもない」スレッドになるが、さらに、実行が進む。この結果、いずれ、「同期で停止する」か「時間待ちで停止する」のどちらかになる。つまり、「どちらでもない」スレッドが０個になる。これを繰り返すことにより、時間管理ができるのである。このようにすると、複数スレッドの連携記述（例えば、データフロー記述）を、基本的には、変えることなく、時間の概念を含めた動作を、コンピュータ上で、実行できるようになる。詳述はしないが、割り込みも、部品そのものは、割り込み信号を直接参照しているわけではないので、図３７、図３８のように、疑似的な割り込み動作を実現することはでき、この場合、ｇｕａｒｄ（）こみの動作も実現可能になる。
【０１１２】
本発明には、後述するが、スレッドごとの機能と、複数スレッドの連携制御を分ける働きがあるといいうる。この働きは、抽象的なシミュレーションにも、効果がある。すなわち、コプロセッサと同等の動作をする機能を書いて、この機能を、ｓｅｔｕｐ（）とｇｕａｒｄ（）の代わりに、実装すれば、複数スレッドの連携制御は同じものを利用しつつ、ソフトウェアによる機能実装による動作実現が可能になる。これにより、実機でも利用しているのと同じ、複数スレッドの連携制御を利用した、機能シミュレーションが可能になる。抽象度が高いレベルから、段階的に、実装・実行を繰り返しながら、ソフトウェアを実現する場合、しばしば、異なる段階の結果同士を比較して、問題点を推測する解析が行われる。このような解析を効率化する方法には、問題点を探す探索空間を減らすことがある。本発明は、異なる段階間で、バグが入りやすいと推測される制御部分（つまり、早期にバグがない状態にしたい部分）を共通化し、しかも早期に動作可能にしているので、後期のデバッグにおいて、重要部分が安全であり、かつ、探索空間を削減されていて効率的になっていると推測しうる。したがって、段階的なソフトウェア開発における生産性の向上を生んでいるといいうる。さらに、後述するが、ＬＳＩ（Ｌａｒｇｅ  Ｓｃａｌｅ  Ｉｎｔｅｇｒａｔｅｄ）のラインナップ上、同一の機能を、ソフトウェア実現とコプロセッサ実現との２つの実装を用意しなければならない場合がある。上記は、ソフトウェア実現とコプロセッサ実現の両方を統一的に開発しているともいえるので、生産性が向上していると推測しうる。さらに、コプロセッサ機能の新規開発を行い、その機能を高位合成で開発する場合には、高位合成に入力する記述を実行していることになり、機能シミュレーションをしている効果があるといいうる。したがって、高位合成を用いた統一的な開発方法論においても、利点があるといいうる。
【０１１３】
このような機能があると、コンピュータ上で実行でき、ガントチャート２００４を作成して画面２００３をディスプレイ５０９に表示することもでき、開発早期に、開発システム上でプログラムコード１０４を動作させた場合の直観を得ることができるのである。そのため、利用者による、複数スレッドの連携（例えば、データフロー）の分析作業を支援することができる。このため、利用者によるソフトウェアの仕様作成の容易化を図ることができる。また、上記のように、重要な部分（ソフトウェアアーキテクチャといってもよい）から立ち上げて、段階的にソフトウェア開発・デバッグをしながら実現していくことが可能になっているので、ソフトウェアを早く安定化させられる可能性も出てくることが考えられる。したがって、このような開発方法論を了すれば、更なる生産性の向上が見込める。
【０１１４】
本実施の形態では、複数のコプロセッサの制御を行う並列動作用のソフトウェアプログラムを作成する例を示したが、これに限らず、機能をソフトウェアで実現したスレッドの実行を行う並列動作用のソフトウェアプログラム１０４を作成してもよい。例えば、ｓｅｔｕｐ（）やｇｕａｒｄ（）の代わりに、コプロセッサが行う処理そのものをソフトウェアで記述した場合、並列スレッドの制御を行う並列動作用のソフトウェアプログラムを作成したことになる。つまり、マルチスレッドのソフトウェア開発においても、本発明は、利用できる場合がある。さらに、コプロセッサで機能を実現したスレッドとソフトウェアで機能を実現したスレッドが、混在しても、複数スレッドの連携のしくみは同じものが利用できる。つまり、実装形態に依存する部分と、複数スレッドの連携制御が分離されていることになる。したがって、制御部分は共通化されているのである。このような性質も、前述のとおり、本実施の形態による利点である。例えば、同一の機能なのに、低価格ＬＳＩではソフトウェアで機能実現だが、高価格ＬＳＩではコプロセッサで機能実現、といったシリーズのＬＳＩもありうる。このような場合、制御部分は共通化されているので、機能実現の形態が違う部分だけを、個別管理すればよいため、ソフトウェア開発の容易化を図ることができる。
【０１１５】
（設計支援装置１００が行う処理手順例）
図２３は、設計支援装置が行う処理手順例を示すフローチャートである。ここでは、実際に運用する対象のプロセッサに生成される並列動作用のプログラムコードの実行形式１０５がロードされた場合の処理手順例を示す。
【０１１６】
まず、設計支援装置１００は、例えば、プログラムコード１０４を取得する（ステップＳ２３０１）。つぎに、設計支援装置１００は、プログラムコード１０４と部品１０２ａｂｃとを組み合わせた並列動作用のプログラムコードの実行形式１０５を生成する（ステップＳ２３０２）。ここでは、並列動作用のプログラムコードの実行形式１０５はコンパイルされた後のデータであるとする。前述のとおり、ＣＰＵ上でインタプリタが動作し、並列動作用のプログラムコード１０４が、インタプリタ上で動作する場合、並列動作用のプログラムコード１０４をインタプリタにロードするとしてもよい。このようにしても、本質的には同じなので、コンパイル後の実行形式１０５を利用したフローで説明する。
【０１１７】
そして、設計支援装置１００は、並列動作用のプログラムコードの実行形式１０５を実行する（ステップＳ２３０３）。これにより、実装すべきソフトウェアが実行される。ステップＳ３３０２で、実行時にデバッグ情報をとりたい場合には、デバッグ用の実行履歴を出力する部品１０２ａｂｃを使ってプログラムコードを生成する。この場合、Ｓ２３０３と並行して、ステップＳ２３０４が実行される。これにより、設計支援装置１００は、並列動作用のプログラムコード１０５を対象のプロセッサにロードさせて実行させた場合の実行履歴１０６を取得する（ステップＳ２３０４）。
【０１１８】
つづいて、設計支援装置１００は、実行履歴１０６に基づいてガントチャート２００４を作成する（ステップＳ２３０５）。そして、設計支援装置１００は、作成したガントチャート２００４を表示し（ステップＳ２３０６）、一連の処理を終了する。
【０１１９】
＜詳細例＞
以降、図２４〜図４９に基づいて、本実施の形態にかかる各クラスや実行例などの詳細例を示す。まず、データフロー７００が示すノード集合とノード間の入出力関係とが、ノードクラスと、割り込みとノードとの対応表のクラスと、同期クラスと、によって記述される。そのため、ノードの基本クラスと、対応表のクラスと、同期クラスと、について詳細に説明する。
【０１２０】
図２４は、ノードの基本クラスの記述例を示す説明図である。記述情報２４００には、ノードの基本クラスが記述される。図２４に示すノードクラスは、ノードの基本クラスである。そのため、ノードクラスでは、このクラスを継承して、ｒｕｎをオーバーライド定義することにより、スレッド実行する関数を定義する。また、ノードの基本クラスでは、メンバー関数ｃｒｅａｔｅ，ｊｏｉｎ，ｌｏｃｋ，ｕｎｌｏｃｋが定義されてある。ノードの基本クラスでは、ｍ＿ｍｕｔｅｘが利用されてある。
【０１２１】
ノードの基本クラスには、ｍ＿ａｃｔｉｏｎというｐｔｈｒｅａｄ＿ｃｏｎｄ＿ｔも定義されてある。ｍ＿ａｃｔｉｏｎは、ａｃｔｉｏｎ（）が呼ばれると、ｇｕａｒｄ（）でブロックされている状態から抜ける動作を行う。
【０１２２】
図２５は、ノードクラスと割り込み例を示す説明図である。ノードクラスでは、ｌｏｃｋ（）の記述とｕｎｌｏｃｋ（）の記述との間に、コプロセッサへの設定とｇｕａｒｄ（）とが記述される。
【０１２３】
スレッドカーネルは、割り込み信号とノードオブジェクトとを割り込みとノードとの対応表に記録しておき、割り込みハンドラによって割り込みＩＤを取得し、割り込みＩＤによって対象のノードオブジェクトの参照を得る。そして、スレッドカーネルは、参照を得たノードオブジェクトのａｃｔｉｏｎ（）をコールする。これにより、Ｎｏｄｅ＿ｔはアクションから抜ける。したがって、ｇｕａｒｄ（）は、対応するコプロセッサが正常に終了するのを待機することになる。ｃｒｅａｔｅによってスレッドが生成されると、ｒｕｎ＿ｂａｓｅクラス関数を経由して、ｒｕｎ関数がスレッド上で実行される。
【０１２４】
図２６は、割り込みとノードとの対応表例を示す説明図である。記述情報２６００には、割り込みとノードとの対応表が記述される。対応表によれば、割り込みハンドラで、終了の割り込みを検出した際に、対応表オブジェクトのメンバー関数ｏｐｅｒａｔｏｒ［］（）の引数として、割り込みＩＤを渡すと、割り込みに関係するノードオブジェクトの参照が得られる。ｏｐｅｒａｔｏｒは、Ｃ＋＋の演算のオーバーロード定義をするための予約語である。ｏｐｅｒａｔｏｒ［］（）は、演算［］を定義している。この定義により、Ｉｎｔ＿ｔｏ＿ｓｉｇ＿ｔのインスタンスをｉｎｔ＿ｔａｂｌｅとした時、ｉｎｔ＿ｔａｂｌｅ［１００］と書くと、引数を１００として関数ｏｐｅｒａｔｏｒ［］が呼ばれ、結果、１００に関係づけられたノードオブジェクトへの参照が得られる。
【０１２５】
図２７は、同期例を示す説明図である。同期クラスは同期のしかたごとに用意される。同期のしかたとは、例えば、ダブルバッファやリングバッファなどである。ここでは、ダブルバッファが利用される。そして、ノードオブジェクトＮ０とノードオブジェクトＮ１とノードオブジェクトＮ２とのすべてが同期に入った時に、同期がとれたとみなされる。そして、ノードオブジェクトＮ０とノードオブジェクトＮ１とノードオブジェクトＮ２とはいずれも同期の部分を抜けてつぎの処理を開始することができる。また、「同期がとれたとみなす」条件が、前述の説明で、同期条件と呼んでいたものである。
【０１２６】
ノードオブジェクトＮ０、ノードオブジェクトＮ１に関しては、処理を実行する際に、ｓｙｎｃ＿０の中のノードオブジェクトＮ０とノードオブジェクトＮ１との出力のデータフィールドに値を書き込むことができる。一方、ノードオブジェクトＮ２は、同期を抜けた後の処理によって、ノードオブジェクトＮ０とノードオブジェクトＮ１とからの出力を受け取ることができる。これにより、上流ノード（スレッド）から下流ノード（スレッド）に伝えたいパラメータを渡すことができる。後述の記述例では、イタレーション回数と一連の処理の最後を示すブール値を渡している。このように、複数スレッドの連携制御（例えば、データフロー制御）に関する情報を、複数スレッドの連携の中で、渡すことができるのである。
【０１２７】
図２８Ａ〜図２９Ｂは、同期クラスと同期ポートクラスの詳細例を示す説明図である。図２８Ａと図２８Ｂとの記述情報２８００には、同期クラスのインターフェースＳｙｎｃ＿ｉｆ＿ｔ、同期ポートクラスＳｙｎｃ＿ｐｏｒｔ＿ｔ、同期ＩＮポートクラスＳｙｎｃ＿ｉｎ＿ｔ、同期ＯＵＴポートクラスＳｙｎｃ＿ｏｕｔ＿ｔが記述されてある。図２９Ａと図２９Ｂとの記述情報２９００には、同期クラスｓｙｎｃ＿ｔが記述されてある。
【０１２８】
Ｓｙｎｃ＿ｉｎ＿ｔ、Ｓｙｎｃ＿ｏｕｔ＿ｔは、データの方向を部品に教える役割ももっている。Ｓｙｎｃ＿ｉｎ＿ｔはｓｙｎｃ＿ｔからデータをもらうポートであることを示す。Ｓｙｎｃ＿ｏｕｔ＿ｔはｓｙｎｃ＿ｔにデータを送るポートであることを示す。これにより、ｓｙｎｃ＿ｔの中に、２つのＤＡＴＡ＿ｔ型を有する記憶領域をＳｙｎｃ＿ｏｕｔ＿ｔの個数分用意される。一方の記憶領域はＳｙｎｃ＿ｏｕｔ＿ｔからの書き込み用として使用される。他方の記憶領域は、Ｓｙｎｃ＿ｉｎ＿ｔからの参照用として使用される。Ｓｙｎｃ＿ｔに繋がるポートがすべてメンバー変数ｓｙｎｃ（）に入った時に、Ｓｙｎｃ＿ｏｕｔ＿ｔ用と、Ｓｙｎｃ＿ｉｎ＿ｔ用と、を入れ替える処理が行われる。入れ替える処理とはｕｐｄａｔｅ（）である。これにより、ｓｙｎｃ＿ｔへデータを送る側と、ｓｙｎｃ＿ｔからデータを受け付ける側が並列に動作しても動作が破綻しないようにしてある。
【０１２９】
図２９Ａおよび図２９Ｂに示す例では、ｂｒｏａｄｃａｓｔによって同期待ち状態を起こしている。また、最後にｓｙｎｃ（）をコールしたスレッドが最後にｓｙｎｃ（）を抜けるようにしている。これは実行順序制御の一例である。さらに、スレッドを起こす際に優先順位をつけ、優先順位によって起こしてもよい。例えば、同期オブジェクトに先に入ったものほど、優先順位が高いとしてもよい。例えば、同期オブジェクトは、各々のスレッドに対応したイベントを用意し、優先順位順に起こす。これにより、同期した際の関連するノードの実行順序のスケジューリングが可能になる。例えば、スレッドカーネルは、コプロセッサに割り当てられる処理の処理時間に基づいて、ノードからコプロセッサに設定する処理の順を決定してもよい。同期クラスは、同期条件を有するとしたが、より正確には、同期条件とスレッドの実行順序の決定方法を有する。
【０１３０】
つぎに、データフロー７００の記述例を示す。ここでは、データフロー７００の制御について示すため、図２４に示すＩＮＴ＿ＭＯＤＥＬディレクティブが指定されていない場合を示す。図２４に示すＩＮＴ＿ＭＯＤＥＬディレクティブが指定されると、図２４や図２５に示すｇｕａｒｄ（）が有効化される。つぎに、ノードの記述例を図３０〜図３２に示す。
【０１３１】
図３０は、ｓｏｕｒｃｅ＿ｔの記述例を示す説明図である。記述情報３０００には、ノードｓｏｕｒｃｅに応じたノードクラスｓｏｕｒｃｅ＿ｔが記述されてある。
【０１３２】
図３１は、ｐａｌａ＿ｔおよびｓｏｌｏ＿ｔの記述例を示す説明図である。記述情報３１００には、ノードＰａｌａおよびノードｓｏｌｏに応じたノードクラスｐａｌａ＿ｔおよびノードクラスｓｏｌｏ＿ｔが記述されるが、説明の簡単化のために、ｐａｌａ＿ｔとｓｏｌｏ＿ｔの記述例を共通化してある。
【０１３３】
図３２は、ｓｉｎｋ＿ｔの記述例を示す説明図である。記述情報３２００には、ノードｓｉｎｋに応じたノードクラスｓｉｎｋ＿ｔが記述されてある。
【０１３４】
ここでは、図３０〜図３２に示す各ノードの記述の簡単化のため、記述情報３０００〜記述情報３２００には、コプロセッサの制御の記述が省略され、当該制御の記述の代わりにプリント文が記述されてある。また、このプリント文による標準出力結果を使って、動作内容を説明する。
【０１３５】
図３３は、ノードの接続記述例を示す説明図である。記述情報３３００は、プログラムコード１０４である。記述情報３３００には、ノードクラスのインスタンス、すなわち、ノードオブジェクトと、同期クラスのインスタンス、すなわち、同期オブジェクトと、ノードオブジェクトと同期オブジェクトの接続が記述される。
【０１３６】
接続記述では、Ｓｙｎｃ＿ｔがインスタンスされる。詳細例で示すＳｙｎｃ＿ｔはテンプレートクラスになっており、テンプレートの引数としては、パラメータの受け渡しに使われるデータ領域の型をとっている。図３３の例では、図３４に示すｄａｔａ＿ｔを指定している。
【０１３７】
図３４は、ｄａｔａ＿ｔの記述例を示す説明図である。記述情報３４００には、出力データのデータ型が記述される。ｄａｔａ＿ｔにはデータフィールドが２つある。１つめのデータフィールドにはイタレーションの回数値が保持される。もう１つのデータフィールドには、一連の処理の最後の場合に真になるフラグが保持される。
【０１３８】
図３０〜図３２の説明に戻る。図３０のように、ｓｏｕｒｃｅ＿ｔは、２０回繰り返しをしたら、終了フラグを送信し、処理を終了している。図３１のように、データフローの中間ノードでは、もらってきたパラメータを、そのまま、下流ノードに渡している。また、一連の処理の最後を示すフラグを参照して、最後だったら終了する。図３２は、他のノードを起動しない例である。このノードでは、受け取ったデータを参照して、一連の処理の最後を示すフラグが真だったら、処理を終わるようにしてある。このように、ノード間の制御を同期させることができるのである。
【０１３９】
図３３の説明に戻る。図３３の接続記述では、ノードオブジェクトのインスタンス、同期オブジェクトのインスタンス、ノードオブジェクトと同期オブジェクトとの接続、ノードオブジェクトをｃｒｅａｔｅ、ノードオブジェクトをｊｏｉｎ、が定義されてある。ノードオブジェクトをｃｒｅａｔｅとは、スレッドを実行することを示す。ノードオブジェクトをｊｏｉｎとは、スレッドの終了により同期することを示す。このように、接続記述は、データフロー７００を形式的に記述したものである。
【０１４０】
設計支援装置１００は、記述情報３３００をコンパイルして実行すると、標準出力として以下の図３５Ａ〜図３５Ｃに示す結果を得る。
【０１４１】
図３５Ａ〜図３５Ｃは、実行によって得られる標準出力例を示す説明図である。この標準出力結果３５００によれば、同期条件を充たしつつ、複数のスレッドによる並列動作が行えていることがわかる。
【０１４２】
図３６は、ｓｏｕｒｃｅ＿ｔの他の記述例を示す説明図である。図２８Ａ〜図３５Ｃで、複数スレッドの連携動作の一例としてデータフロー動作を説明した。図３６〜図３９で、割り込みに関する、コプロセッサとノードの連携について説明する。図３６にノードクラス例を示す。記述情報３６００は、ノードｓｏｕｒｃｅに対応する図３０に示すノードオブジェクトｓｏｕｒｃｅ＿ｔと異なるノードオブジェクトの記述例である。記述情報３６００は、ｇｕａｒｄを利用した記述例である。なお、図２４に示すＩＮＴ＿ＭＯＤＥＬディレクティブが指定された状態、つまり、割り込みがノードに届く形態であるとする。
【０１４３】
図３７は、ノードの接続記述の他の例を示す説明図である。記述情報３７００では、ノードオブジェクトｓｏｕｒｃｅ＿ｔと割り込みを模擬するノードオブジェクトｉｎｔｅｒｒｕｐｔ＿ｔとがインスタンス化されている。ノードオブジェクトｉｎｔｅｒｒｕｐｔ＿ｔは、ｇｕａｒｄ（）を説明するために便宜的に導入したもので、ＨＤＬ（Ｈａｒｄｗａｒｅ  Ｄｅｓｃｒｉｐｔｉｏｎ  Ｌａｎｇｕａｇｅ）記述におけるテストベンチに相当するものである。ｉｎｔｅｒｒｕｐｔ＿ｔの記述例を図３８に示す。
【０１４４】
ｒｕｎ（）記述では、１秒ごとに、割り込みＩＤ１００に対する割り込みを受け取って、割り込みＩＤ１００に対応するノードオブジェクトに割り込みを通知する。このようにして、割り込みと割り込みハンドラの連携で実現する動作を模擬している。実際の利用では、図３８の（２）の記述を、割り込みハンドラの中で識別した割り込みＩＤを使って、図３８と同様、ｇ＿ｉｎｔ＿ｔｏ＿ｓｉｇ［ｉｎｔ＿ｉｄ］で、ノードの参照を得て、そのメンバー関数ａｃｔｉｏｎ（）を呼ぶ。したがって、実際と模擬の差は、割り込みハンドラの中でａｃｔｉｏｎ（）が呼ばれるか、ダミーのスレッドの中で、適当な間隔で、ａｃｔｉｏｎ（）が呼ばれるかの差だけなので、割り込みがノードに伝わるしくみ自体は同じである。このようにして、複数スレッドの連携を構成するスレッドに対して、割り込みがかかる。ノード（スレッド）がコプロセッサの代理人（例えば、図９）として、コプロセッサの動作状況をまねながら動いている状態を作ることができる。したがって、利用者は、複数コプロセッサの連携制御を、コプロセッサの代理人である複数ノードを、複数スレッドの連携制御（例えば、データフロー制御）で結合することで、ソフトウェア開発ができるのである。
【０１４５】
そして、記述情報３７００には、ノードオブジェクトｓｏｕｒｃｅ＿ｔと割り込み用のノードオブジェクトｉｎｔｅｒｒｕｐｔ＿ｔとが、並列のスレッドとして、生成されることが記述されてある。また、記述情報３７００には、ノードオブジェクトｓｏｕｒｃｅ＿ｔのスレッドとｉｎｔｅｒｒｕｐｔ＿ｔのスレッドとが、ともに終了すると、全体の処理を終了するように記述されている。ただし、図３８の場合、スレッドが終了しない。この記述例は、コンピュータ上で実行するものだったので、所望の応答が得られたら、プロセスをｋｉｌｌすることで処理を終了させていた。
【０１４６】
図３８は、ｉｎｔｅｒｒｕｐｔ＿ｔの記述例を示す説明図である。ｒｕｎ（）の動作は前記の通りである。
【０１４７】
図３９は、実行によって得られる標準出力の他の例を示す説明図である。標準出力結果３９００では、コプロセッサとノードとが関連付けられたことを示している。図３６の記述情報３６００では、図２５に示したようにｇｕａｒｄ（）を利用してノードオブジェクトｓｏｕｒｃｅ＿ｔが定義されている。そのため、上述したように、割り込みハンドラで、コプロセッサの終了を検出して、「ｇ＿ｉｎｔ＿ｔｏ＿ｓｉｇ［ｉｎｔ＿ｉｄ］．ａｃｔｉｏｎ（）」が呼ばれると、ａｃｔｉｏｎ（）の中で、スレッドプログラミングにおける信号が呼ばれ、スレッドはｇｕａｒｄ（）の中でこの信号待ちをしているので、ｇｕａｒｄ（）を抜け、処理を再開するのである。
【０１４８】
これにより、起動から終了の間、ノード（スレッド）は休止していることになる。つまり、簡便な記述ながら、ノード（スレッド）は、コプロセッサの動作を模擬しているのである。したがって、ｇｕａｒｄ（）を抜けたところに、下流ノードと同期をとると記述しておけば、同期条件にあったコプロセッサ間のデータ転送が実現されるのである。また、コプロセッサが実行中、スレッドが休止していることも重要で、この間、他のスレッドの動作を妨げない。つまり、おおむね、制御にかかわる判断が必要な時と、コプロセッサの設定が必要な時とに、動作するものができているのである。まとめると、複数スレッドの連携を実現する同期クラスと、ノードとコプロセッサを連携させる技術（ノードクラスの一機能）とを使うと、ノード（スレッド）はコプロセッサの状態を模擬することになるので、複数ノードを、複数スレッドの連携制御でつなぐだけで、複数コプロセッサの連携制御ができるようになるのである。冒頭で書いたように、従来は、この制御を実現するために、仕様検討、詳細化が必要であった。しかし、本発明によれば、複数コプロセッサと対応付けられたノードを、直観的に、つなぐだけで、所望の機能が得られるのである。したがって、安全に、わかりやすい形で、機能実現が可能になった、といってよい。
【０１４９】
本実施の形態では、利用者は、データフロー７００の定義を形式的に記述するだけである。そのため、利用者は、データフロー７００の作成以外に新たな構築作業を行わずに、並列動作用のプログラムコード１０５を簡単に得ることができる。
【０１５０】
また、図３７に示したように、コプロセッサとノードとを関連付ける記述例は、コプロセッサ単体の制御を行う記述である。図３６に示したように、ノードはｇｕａｒｄ（）でなされる、コプロセッサからの割り込み待ちから抜けるのを待つという記述になる。そのため、利用者はＦＳＭを考えることなく、ソフトウェアの実装を行うことができるのである。
【０１５１】
したがって、複数のコプロセッサの連携を行う並列動作用のプログラムコードの作成の簡単化を図ることができる。
【０１５２】
図４０は、段階的な設計フロー例を示す説明図である。利用者が、制御記述のないスケルトン記述を作成する（ステップＳ４００１）。制御記述とは、コプロセッサを制御するための記述である。そして、設計支援装置１００は、同期クラスと、ノードクラスと、データフロー７００が示す入出力関係を同期クラスおよびノードクラスによって記述したプログラムコードと、によってコンパイルして実行する（ステップＳ４００２）。これにより、標準出力結果によってガントチャート２００４を作成することができる。このように、コプロセッサ間の制御の関連性部分の記述を開発して簡単に検証することができる。また、前述のような時間管理クラスや、割り込み模擬クラスを導入して、制御記述の一部も利用可能にして、実行するとしてもよい。
【０１５３】
また、利用者が、スレッドについての制御記述を追加して、並列動作用のプログラムコード１０５を作成する（ステップＳ４００３）。制御記述とは、コプロセッサに対する設定とコプロセッサからの割り込み待ちなどの制御である。そして、設計支援装置１００は、並列動作用のプログラムコード１０５をコンパイルして実行する（ステップＳ４００４）。これにより、ガントチャート２００４を作成することができる。
【０１５４】
つぎに、設計支援装置１００は、コンパイル後の並列動作用のプログラムコード１０５を実機にロードして実行する（ステップＳ４００５）。実機は、例えば、上述したシステム２０００やシステム２０００をプログラミング言語によってモデル化したものである。そして、設計支援装置１００は、実行履歴２００２に基づいてガントチャート２００４を作成する（ステップＳ４００６）。
【０１５５】
ここで、ステップＳ４００２やステップＳ４００４のように、プログラムをコンパイルして実行するだけで、ガントチャート２００４を得られるようにするためには、以下図４１のような記述が追加される。
【０１５６】
図４１は、ガントチャート作成のための追加記述例を示す説明図である。記述情報４１００に示すように、図２８Ａおよび図２８Ｂ、図２９Ａおよび図２９Ｂなどに示す記述情報２８００や記述情報２９００には、イベントの発生前後においてイベントの発生起因をダンプできる記述が追加される。
【０１５７】
図４２は、ガントチャート作成のための接続記述例を示す説明図である。記述情報４２００には、ノードオブジェクトと同期オブジェクトとのインスタンスの際に、下線の箇所のように、オブジェクトを示す名称を受け渡すように記述される。また、記述情報４２００には、Ｐｏｒｔ｛ｏｕｔ，ｉｎ｝にノードの名称を渡すために、ノードそのものを渡すように記述される。
【０１５８】
図４３Ａ〜図４３Ｅは、図４１および図４２に示した記述情報に基づく実行結果例を示す説明図である。設計支援装置１００は、図４１に示した記述情報４１００と図４２に示した記述情報４２００とをコンパイルして実行することによって実行結果４３００を得る。
【０１５９】
実行結果４３００には、スレッドの実行開始のタイミングと、Ｓｙｎｃ（）に入ったタイミングまたは出たタイミングと、スレッドの実行終了のタイミングと、が含まれる。
【０１６０】
図４４は、接続関係の記述例を示す説明図である。接続関係情報４４００は、ノードオブジェクトと同期オブジェクトとの接続関係が記述される。この情報は、プログラムコード１０４を解析して、出力してもよいし、部品１０２ｂｃを、この記述を出力するように拡張した部品を使って、プログラムコードの実行形式１０５を生成し、実行形式を実行すると、図４４が出力されるようにしてもよい。
【０１６１】
図４５は、作成されるガントチャート例を示す説明図である。設計支援装置１００は、接続関係情報４４００と、実行結果４３００と、に基づいてガントチャート２００４を作成してディスプレイなどに表示する。ガントチャート２００４では、ノードオブジェクトと同期オブジェクトの各々について、入力待ち、処理中、出力待ち、などの状態と、各イベントの発生タイミングと、が可視化される。
【０１６２】
設計支援装置１００は、キーボード５０７やマウス５０８などの入力装置を介して利用者によって開始ノードオブジェクトの指定を受け付ける。または、図４４より、ｏｕｔ＝””のみに出現するノードオブジェクトを選択するとしてもよい。このようなノードは入力側に同期オブジェクトがいないので、開始ノードオブジェクトである。設計支援装置１００は、開始ノードオブジェクトが指定された場合、開始ノードオブジェクトは、ガントチャートの先頭が「処理中」になるようにガントチャート２００４を作成する。また、設計支援装置１００は、入力待ちがある場合には、入力待ちを抜けた場合に「処理中」の状態となるようにガントチャート２００４を作成する。入力待ちがない場合、出力待ちを抜けた場合に「処理中」の状態となるようにガントチャート２００４を作成する（例えば、図中、Ｓｒｃ）。また、設計支援装置１００は、ガントチャート２００４を９０度回転させたシーケンス図を作成してもよい。
【０１６３】
つぎに、ソフトウェアで機能実装したスレッドの例を示す。図４６Ａ〜図４６Ｃは、印字回数を増やした記述例を示す説明図である。ここでは、ｇｕａｒｄ（）は空関数（図２４の記述例でディレクティブＩＮＴ＿ＭＯＤＥＬが設定されていない状態）で、コメントアウトされているのと同等の状態である。この時、ノードオブジェクトにおいて、ｌｏｃｋ（）〜ｕｎｌｏｃｋ（）は、連続実行される。記述情報４６００では、矢印で示した部分のように所定回数分の印字が、連続して、行われる。ＩＮＴ＿ＭＯＤＥＬが設定されている場合には、ｌｏｃｋ（）〜ｇｕａｒｄ（）間が連続実行され、コプロセッサが割り込み信号を上げるまで、ｇｕａｒｄ（）の中で、スレッドは休止する。ここでは複数スレッドの連携動作を、コンピュータ上で可視化したいので、ｇｕａｒｄ（）を空関数にしている。
【０１６４】
図４７は、図４６Ａ〜図４６Ｃの記述情報に基づく実行結果例を示す説明図である。図４７に示す実行結果４７００によれば、ｌｏｃｋ（）〜ｕｎｌｏｃｋ（）が連続実行されている。コプロセッサ制御の場合は、前述のとおり、ｌｏｃｋ（）〜ｇｕａｒｄ（）が連続実行される。このような動作になるのは、ｕｎｌｏｃｋ（）と同様、ｇｕａｒｄ（）でも、クリティカルセクションを抜けるためである。これにより、設定が連続していることが望まれるコプロセッサに適した動作となる。
【０１６５】
図４８Ａ〜図４８Ｃは、印字回数を増やした他の記述例を示す説明図である。記述情報４８００では、ｌｏｃｋ（）、ｕｎｌｏｃｋ（）、ｇｕａｒｄ（）が削除されてある。そのため、ノードオブジェクトにおいて、ｌｏｃｋ（）とｕｎｌｏｃｋ（）がないので、連続実行されない。
【０１６６】
図４９は、図４８Ａ〜図４８Ｃの記述情報に基づく実行結果例を示す説明図である。図４９の実行結果４９００によれば、同期条件は満たすものの、実行は、複数のスレッドの実行がインターリーブされていることがわかる。つまり、ノードオブジェクトの機能が並列実行されているのである。例えば、ノードｓｏｕｒｃｅの処理の４番目、ノードｐａｒａ＿０，ｐａｒａ＿１，ｐａｒａ＿２，ｐａｒａ＿３の各々の３回目、ノードｓｏｌｏの処理の２回目、ノードｓｉｎｋの処理の１回目が並列に動作していることを判別できる。このように、同期条件を満たしつつ、スレッドで実現した機能は、インターリーブして動作される。機能をソフトウェア実現した場合にこのような動作が好まるので、機能をソフトウェア実現した場合に適した動作ができていることがわかる。
【０１６７】
このように、データフロー７００の制約にあった形で、複数のスレッドが並列動作させられ、機能をコプロセッサ実現した場合に好まれる実行も、ソフトウェア実現した場合に好まれる実行も実現しうることがわかる。
【０１６８】
以上説明したように、設計支援装置１００は、複数スレッドを、同期オブジェクトが定める同期条件で、同期した動作をする複数スレッドで構成された、並列動作用のプログラムコードを生成する。実施の形態で説明したように、ダブルバッファに対応した同期オブジェクトで、スレッドを連携させると、ダブルバッファで破綻しないデータフロー制御ができる並列動作用プログラムが生成できる。このように、並列動作用のプログラムコードの作成の容易化を図ることができる。
【０１６９】
また、設計支援装置１００は、並列動作用のプログラムコードの実行中に、同期をとる関数に入ったタイミングと出たタイミングとを動作履歴として記憶し、各タイミングに基づいてスレッドの各々についての動作の流れを示す図、例えば、ガントチャートやシーケンス図などが、簡単に表示しうる。したがって、利用者は、データフローなどの仕様作成中に、ガントチャートなどを確認することができるため、仕様などの分析作業の容易化を図ることができる。
【０１７０】
また、設計支援装置１００は、さらに、データフローが示すスレッドをノードクラスで記述したプログラムコードによって並列動作用のプログラムコードを生成する。これにより、スレッドを簡単にコードに表すことができるため、読みやすいプログラムコードを簡単に作成することができる。
【０１７１】
また、並列動作用のプログラムコードが複数のコプロセッサを連携して動作させるための制御プログラムである場合、ノードクラスには、コプロセッサに対する設定を行う処理と、コプロセッサからの割り込みを受け付ける処理と、が定義される。これにより、複数のコプロセッサを連携して動作させるための並列動作用のプログラムコードを簡単に得ることができる。また、スレッドの機能を一部共通化させることができるため、読みやすいプログラムコードを簡単に作成することができる。
【０１７２】
また、設計支援装置１００は、並列動作用のプログラムコードを実行中に、同期をとる関数に入ったタイミングと出たタイミングとを、または、割り込みのタイミングとを動作履歴として記憶し、記憶した各タイミングに基づき、複数のコプロセッサの各々についての制御動作の流れを示す図を表示する。これにより、コプロセッサの動作の流れを簡単に可視化することができる。したがって、ソフトウェアのデバッグ作業の容易化を図ることができ、ソフトウェアの開発期間の短縮化を図ることができる。
【０１７３】
なお、本実施の形態で説明した設計支援方法は、予め用意された設計支援プログラムをパーソナル・コンピュータやワークステーション等のコンピュータで実行することにより実現することができる。本設計支援プログラムは、磁気ディスク、光ディスク、ＵＳＢ（Ｕｎｉｖｅｒｓａｌ  Ｓｅｒｉａｌ  Ｂｕｓ）フラッシュメモリなどのコンピュータで読み取り可能な記録媒体に記録され、コンピュータによって記録媒体から読み出されることによって実行される。また、設計支援プログラムは、インターネットなどのネットワーク５１０を介して配布してもよい。
【０１７４】
上述した実施の形態に関し、さらに以下の付記を開示する。
【０１７５】
（付記１）入力される複数のスレッドを同期する際の同期条件を記憶する記憶部と、
前記複数のスレッドに対して、前記同期条件に応じた制御を行う同期手段と、
利用者が作成する前記複数のスレッドと、前記複数のスレッドのそれぞれと前記同期手段を関係づける記述情報と、に基づいてソフトウェアを生成する生成部と、
を有することを特徴とする設計支援装置。
【０１７６】
（付記２）前記複数のスレッドを同期した実行履歴を出力する出力手段を有することを特徴とする付記１に記載の設計支援装置。
【０１７７】
（付記３）前記スレッドがコプロセッサを制御する場合であって、
前記記憶部は、
前記コプロセッサが送信した割り込みを前記スレッドに出力する手段を有し、
前記生成部は、
割り込み識別番号と前記スレッドを関係づける情報に基づいて前記コプロセッサが送信した割り込みを前記スレッドに出力することを特徴とする付記１に記載の設計支援装置。
【０１７８】
（付記４）前記割り込み、または、前記複数のスレッドを同期した実行履歴を出力する出力手段を有することを特徴とする付記３に記載の設計支援装置。
【０１７９】
（付記５）出力した前記実行履歴を解析して、前記スレッドの変化を示す図を表示する表示手段を有することを特徴とする付記２または付記４に記載の設計支援装置。
【０１８０】
（付記６）入力される複数のスレッドを同期する際の同期条件を記憶し、
前記複数のスレッドに対して、前記同期条件に応じた制御を同期手段が行い、
利用者が作成する前記複数のスレッドと、前記複数のスレッドのそれぞれと前記同期手段を関係づける記述情報と、に基づいてソフトウェアを生成することを特徴とする設計支援方法。
【０１８１】
（付記７）入力される複数のスレッドを同期する際の同期条件を記憶し、
前記複数のスレッドに対して、前記同期条件に応じた制御を同期手段が行い、
利用者が作成する前記複数のスレッドと、前記複数のスレッドのそれぞれと前記同期手段を関係づける記述情報と、に基づいてソフトウェアを生成することを特徴とする設計支援プログラム。
【符号の説明】
【０１８２】
１００  設計支援装置
１０２  記憶部
１０２ａ  同期クラス
１０２ｂ  同期ポートクラス
１０２ｃ  基本ノードクラス
１０４  プログラムコード
１０５  実行形式
１１１〜１１３  スレッド
７００  データフロー
２０００  システム
２００１  ＣＰＵ
２００２  実行履歴
２００３  画面
２００４  ガントチャート
Ｃ０〜Ｃ３  コプロセッサ
【図１Ａ】
0006528433.tif 000002
【図１Ｂ】
0006528433.tif 000003
【図１Ｃ】
0006528433.tif 000004
【図２】
0006528433.tif 000005
【図３】
0006528433.tif 000006
【図４】
0006528433.tif 000007
【図５】
0006528433.tif 000008
【図６】
0006528433.tif 000009
【図７】
0006528433.tif 000010
【図８】
0006528433.tif 000011
【図９】
0006528433.tif 000012
【図１０】
0006528433.tif 000013
【図１１】
0006528433.tif 000014
【図１２】
0006528433.tif 000015
【図１３】
0006528433.tif 000016
【図１４】
0006528433.tif 000017
【図１５】
0006528433.tif 000018
【図１６】
0006528433.tif 000019
【図１７】
0006528433.tif 000020
【図１８Ａ】
0006528433.tif 000021
【図１８Ｂ】
0006528433.tif 000022
【図１８Ｃ】
0006528433.tif 000023
【図１８Ｄ】
0006528433.tif 000024
【図１８Ｅ】
0006528433.tif 000025
【図１９】
0006528433.tif 000026
【図２０】
0006528433.tif 000027
【図２１】
0006528433.tif 000028
【図２２】
0006528433.tif 000029
【図２３】
0006528433.tif 000030
【図２４】
0006528433.tif 000031
【図２５】
0006528433.tif 000032
【図２６】
0006528433.tif 000033
【図２７】
0006528433.tif 000034
【図２８Ａ】
0006528433.tif 000035
【図２８Ｂ】
0006528433.tif 000036
【図２９Ａ】
0006528433.tif 000037
【図２９Ｂ】
0006528433.tif 000038
【図３０】
0006528433.tif 000039
【図３１】
0006528433.tif 000040
【図３２】
0006528433.tif 000041
【図３３】
0006528433.tif 000042
【図３４】
0006528433.tif 000043
【図３５Ａ】
0006528433.tif 000044
【図３５Ｂ】
0006528433.tif 000045
【図３５Ｃ】
0006528433.tif 000046
【図３６】
0006528433.tif 000047
【図３７】
0006528433.tif 000048
【図３８】
0006528433.tif 000049
【図３９】
0006528433.tif 000050
【図４０】
0006528433.tif 000051
【図４１】
0006528433.tif 000052
【図４２】
0006528433.tif 000053
【図４３Ａ】
0006528433.tif 000054
【図４３Ｂ】
0006528433.tif 000055
【図４３Ｃ】
0006528433.tif 000056
【図４３Ｄ】
0006528433.tif 000057
【図４３Ｅ】
0006528433.tif 000058
【図４４】
0006528433.tif 000059
【図４５】
0006528433.tif 000060
【図４６Ａ】
0006528433.tif 000061
【図４６Ｂ】
0006528433.tif 000062
【図４６Ｃ】
0006528433.tif 000063
【図４７】
0006528433.tif 000064
【図４８Ａ】
0006528433.tif 000065
【図４８Ｂ】
0006528433.tif 000066
【図４８Ｃ】
0006528433.tif 000067
【図４９】
0006528433.tif 000068