(57)【特許請求の範囲】
【請求項１】
第１の演算プログラムおよび第２の演算プログラムを有するソフトウエアプログラムを実行する計算処理方法であって、
前記第１の演算プログラムを実行する演算実行ステップ、
前記第１の演算プログラムとは独立してその内容が規定された前記第２の演算プログラムを、複数回繰返し実行する繰返実行ステップ、
前記繰返実行ステップにおいて、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存ステップ、
を備える第１の演算ステップと、
前記ソフトウエアプログラムの修正要否に応じて、前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定する復元ポイント指定ステップ、
前記状態保存ステップで保存された計算状態のうち、前記指定された復元ポイントに対応する繰返し回数における前記保存された計算状態を選択して読み出す選択読出ステップ、
前記選択された計算状態に基づいて、前記第２の演算プログラムを実行する復元ステップ、
を備える第２の演算ステップと、
を備えることを特徴とする計算処理方法。
【請求項２】
前記第１の演算プログラムと前記第２の演算プログラムは、前記ソフトウエアプログラムにおいて、それぞれ異なる関数として定義されたことを特徴とする請求項１記載の計算処理方法。
【請求項３】
前記状態保存ステップでは、前記ソフトウエアプログラムにおいて定義されるグローバル変数を、前記グローバル変数の特性に応じた保存方法により保存し、
前記選択読出ステップでは前記保存されたグローバル変数を読み出すこと、
を特徴とする請求項１または２のいずれかに記載の計算処理方法。
【請求項４】
前記状態保存ステップで保存されたグローバル変数を修正する修正ステップを備え、
前記選択読出ステップは、前記修正ステップにおいて修正されたグローバル変数を読み出すこと、
を特徴とする請求項３記載の計算処理方法。
【請求項５】
前記選択読出ステップにおいて読み出されたグローバル変数を修正する読出修正ステップを備え、
前記復元ステップは前記修正されたグローバル変数に基づいて、前記第２の演算プログラムを実行すること、
を特徴とする請求項３記載の計算処理方法。
【請求項６】
計算機に、
第１の演算プログラムを実行する演算実行ステップ、
前記第１の演算プログラムとは独立してその処理内容が規定された第２の演算プログラムを、複数回繰返し実行する繰返実行ステップ、
前記繰返実行ステップにおいて、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存ステップ、
を備える第１の演算手順と、
前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定させる復元ポイント指定ステップ、
前記状態保存ステップで保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出ステップ、
前記選択された計算状態に基づいて、前記第２の演算プログラムを実行する復元ステップ、
を備える第２の演算手順と、
を実行させることを特徴とするソフトウエアプログラム。
【請求項７】
第１の演算プログラムおよび第２の演算プログラムを有するソフトウエアプログラムを実行する計算装置であって、
前記第１の演算プログラムを実行する演算実行手段と、
前記第１の演算プログラムとは独立してその処理内容が規定された前記第２の演算プログラムを、複数回繰返し実行する繰返実行手段と、
前記繰返実行手段において、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存手段と、
前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定する復元ポイント指定手段と、
前記状態保存手段で保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出手段と、
前記選択読出手段で選択された計算状態に基づいて、前記第２の演算プログラムを実行する復元手段と、
を備えることを特徴とする計算処理装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、例えばデバッグを伴うシミュレーションなどを行う計算処理方法、計算処理装置およびソフトウエアプログラムに関する。
【背景技術】
【０００２】
ソフトウエアプログラムを計算機上に適用し、繰返し処理を含む計算を長時間行って得た結果を利用することは多くの分野で行われている。天気予報などはその典型的な例といえる。これらの計算時間については、一瞬で終わるものから数日、あるいはそれ以上かかるものなど様々である。こうしたソフトウエアの開発にあたり、ソフトウエア試験および修正を行い、目的である現象等の評価段階、つまりソフトウエアプログラムを本格的に利用する段階になって、長時間の繰返し計算を行ったところ、これまで出ていなかったソフトウエアの問題（バグ）が見つかることがある。それは多くの場合、長時間の繰返し計算を行うことで、ソフトウエア試験ではカバーしきれなかった事象が発生するためである。
【０００３】
このような場合、ソフトウエアプログラムのデバッグ作業を行い、不具合箇所を発見し、修正する作業を行う必要がある。ソフトウエアプログラムのデバッグを行うには、問題の起きた前後のタイミングで詳細な情報収集を行うため設定を行い、ソフトウエアプログラムを最初から再度長時間の計算を行う必要がある。１回のやり直しで原因がわかり、解決することは稀であり、たとえ１回のやり直しで解決できたとしても、数時間、あるいは数日に及ぶような計算をもう一度実施しなければならず、多くの時間を消費してしまうことになる。したがって、デバッグ作業の効率化はソフトウエア開発を行う上で必要不可欠となる。
【０００４】
デバッグ作業の効率化のため、次のような提案がなされている。特許文献１には、計算プログラムに与える各種のパラメータを、前回の計算結果に基づいて効果的な値になるよう支援するシミュレーション装置が記載されている。このパラメータ設定の手間を減らし、また効果的なパラメータ設定ができれば、評価の回数を減らすことができ、予定よりも短い日数で、所定の結果を得ることができる。また、特許文献２には、プログラムソースの内容から、計算途中の保存に必要なメモリ容量を見積もり、そして計算中、可能な範囲で途中の状況をメモリに保存しておき、保存した時点から計算を再開できるようにすることで、デバッグの時間効率を上げるシミュレーション装置が記載されている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２００６−１４６３６９号公報（第５頁〜第１１頁、図１）
【特許文献２】特開２００６−１７２１０２号公報（第３頁、図１）
【発明の概要】
【発明が解決しようとする課題】
【０００６】
しかしながら、従来のシミュレーション装置ではそれぞれ以下に示すような問題がある。特許文献１に記載のシミュレーション装置では、パラメータを効果的に設定することにより、評価を進める上で計算回数を減らし、目的の効果が得られるまでの時間が短縮されることが考えられるが、繰り返し最初から最後までソフトウエアプログラムを実行する必要があり、例えば、１回の計算に１０時間かかるソフトウエアプログラムにおいては、次の計算にも１０時間を要し、デバッグ作業を行うにあたっては最初から計算しなおして長時間待機しなければならない。
【０００７】
また、特許文献２に記載のシミュレーション装置を用いて繰返し処理を含むソフトウエアプログラムを計算機上に適用し、長時間計算して結果を得て利用するような場合には次のような問題点がある。デバッグのためにプログラムの修正を行った場合、再度コンパイルおよび実行を行う必要があり、長時間の計算を行う必要がある。また、あらかじめ保存に必要なメモリをプログラムソースから算出しており、各保存箇所における保存量をあらかじめ決めているため、シミュレーションに与えるパラメータや初期設定によってプログラム上の同一の箇所(保存箇所)においてメモリ使用量が変化することは許容されず、繰返し処理の度に使用メモリが変化するようなシミュレーションなどでは多くの場合適用できず、汎用的でないという問題がある。
【０００８】
この発明は、上記のような課題を解決するためになされたもので、ソフトウエアプログラムのデバッグ処理の作業効率および汎用性の向上を目的とする。
【課題を解決するための手段】
【０００９】
この発明に係る計算処理方法は、第１の演算プログラムおよび第２の演算プログラムを有するソフトウエアプログラムを実行する計算処理方法であって、前記第１の演算プログラムを実行する演算実行ステップ、前記第１の演算プログラムとは独立してその内容が規定された前記第２の演算プログラムを、複数回繰返し実行する繰返実行ステップ、前記繰返実行ステップにおいて、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存ステップ、を備える第１の演算ステップと、前記ソフトウエアプログラムの修正要否に応じて、前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定する復元ポイント指定ステップ、前記状態保存ステップで保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出ステップ、前記選択された計算状態に基づいて、前記第２の演算プログラムを実行する復元ステップ、を備える第２の演算ステップと、を備える。
【００１０】
また、この発明に係るソフトウエアプログラムでは、計算機に、第１の演算プログラムを実行する演算実行ステップ、前記第１の演算プログラムとは独立してその処理内容が規定された第２の演算プログラムを、複数回繰返し実行する繰返実行ステップ、前記繰返実行ステップにおいて、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存ステップ、を備える第１の演算手順と、前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定させる復元ポイント指定ステップ、前記状態保存ステップで保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出ステップ、前記選択された計算状態に基づいて、前記第２の演算プログラムを実行する復元ステップ、を備える第２の演算手順と、を実行させる。
【００１１】
また、この発明にかかる計算処理装置では、第１の演算プログラムおよび第２の演算プログラムを有するソフトウエアプログラムを実行する計算装置であって、前記第１の演算プログラムを実行する演算実行手段と、前記第１の演算プログラムとは独立してその処理内容が規定された前記第２の演算プログラムを、複数回繰返し実行する繰返実行手段と、前記繰返実行手段において、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存手段と、前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定する復元ポイント指定手段と、前記状態保存手段で保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出手段と、前記選択読出手段で選択された計算状態に基づいて、前記第２の演算プログラムを実行する復元手段と、を備える。
【発明の効果】
【００１２】
この発明によれば、ソフトウエアプログラムのデバッグ処理の作業効率を向上させ、また、汎用性を向上させることができる。
【図面の簡単な説明】
【００１３】
【図１】本発明の実施の形態１に示す計算処理装置の構成を示すブロック図である。
【図２】本発明の実施の形態１に示す計算処理装置における処理の対象となるソフトウエアプログラムの基本構成のフローチャートである。
【図３】本発明の実施の形態１に示すソースプログラムの例を示す図である。
【図４】本発明の実施の形態１に示すソースプログラムの例を示す図である。
【図５】本発明の実施の形態１に示すソースプログラムの例を示す図である。
【図６】本発明の実施の形態１に示すソースプログラムの例を示す図である。
【図７】本発明の実施の形態１に示すソフトウエアプログラムのフローチャートを示す図である。
【図８】本発明の実施の形態１に示すソースプログラムの例を示す図である。
【図９】本発明の実施の形態１に示すソフトウエアプログラムのフローチャートを示す図である。
【図１０】本発明の実施の形態１に示すソースプログラムの例を示す図である。
【図１１】本発明の実施の形態１に示すソースプログラムの例を示す図である。
【図１２】本発明の実施の形態１に示すソースプログラムの例を示す図である。
【図１３】本発明の実施の形態２に示すソースプログラムの例を示す図である。
【図１４】本発明の実施の形態２に示すソースプログラムの例を示す図である。
【図１５】本発明の実施の形態２に示すソースプログラムの例を示す図である。
【図１６】本発明の実施の形態２に示すソースプログラムの例を示す図である。
【図１７】本発明の実施の形態２に示すソースプログラムの例を示す図である。
【図１８】本発明の実施の形態２に示すソースプログラムの例を示す図である。
【図１９】本発明の実施の形態２に示すソースプログラムの例を示す図である。
【図２０】本発明の実施の形態２に示すソフトウエアプログラムのフローチャートをソースプログラムの例を示す図である。
【図２１】本発明の実施の形態２に示すソースプログラムの例を示す図である。
【発明を実施するための形態】
【００１４】
実施の形態１．
図１は、本発明の実施の形態１に係る計算処理装置の構成を示すブロック図である。図において、プログラム実行手段１１は、ソフトウエアプログラムの実行等を行う。メモリ１２は、ソフトウエアプログラムの途中の計算状態および計算結果を保存する。ここではハードディスクドライブを用いる。入力手段１３はソフトウエアプログラムの入力およびパラメータ値の入力を行う。表示装置１４は、プログラム実行手段１１により出力される出力結果、パラメータ値等を表示する。
【００１５】
実施の形態１に係る計算処理装置では、その中に繰り返し演算を含むソフトウエアプログラムの実行、デバッグ等の処理を行う。対象となるソフトウエアプログラムの基本構成のフローチャートを図２に示す。図３に、その動作が図２のフローチャートで表されるソフトウエアプログラムのソースプログラムのうち、最上位にくる記述の簡単な例を示す。なお、ここでは古典的なＣ言語など、オブジェクト指向プログラミングではない言語を用いて適用した場合について示す。図３において、［  ］で示したものはソースプログラムに記載される処理の内容を示しており、他の図においても同様である。図３に示すソースプログラムには、main関数と［グローバル変数宣言］（５１１）が記述されており、［グローバル変数宣言］（５１１）では、main関数から直接、あるいは下位の各関数で共通に参照可能なグローバル変数を記述する。また、main関数には、［ローカル変数の宣言］（５０１）、［初期化処理］（１０１）、繰り返し処理（２０１、２０２）の内部に配置された計算の［本体処理］（３０１）、［後処理］（４０１）が記述される。図３に示すソースプログラムではmain関数に［本体処理］（３０１）を記述する構成としているが、main関数に下位に関数を新たに記述し、本体処理の全部または一部をこの関数の中に記述することも可能であるが、記述上の問題だけであり、ソフトウエアプログラムの動作・構成には影響がない。
【００１６】
このソースプログラムを以下に示すように記述し直すことにより、専用装置を必要とせず汎用的な計算機により実施の形態１に係る計算処理装置を実現することができる。図４に新たに定義するソースプログラムの概略を示す。
【００１７】
図３に示したソースプログラム（以下で、元のソースプログラムとする）の本体処理等の各処理について、それぞれの処理内容を独立して規定してプログラム実行手段１１に実行させるようにする。すなわち、図４に示すように、各処理を以下のオブジェクト（ここでは関数）として定義し、これらをさらに図５に示すように上位のソースプログラムで呼び出す構成とする。図４では、以下の関数を定義している。
１．initialize(コマンド引数)
元のソースプログラムの初期化処理を含む。必要に応じコマンド引数をそのまま引数として受け取る。
２．main_calc(引数)
元のソースプログラムの繰り返し処理の本体処理（繰返し処理における１回分の処理）を含む。引数には繰返し処理の繰り返し数を含む。
３．finishing
元のソースプログラムの後処理を含む。例えば、結果の出力処理などを規定する。
【００１８】
各処理を関数化したことで、それぞれの関数の中でローカル変数を宣言しているほか［ローカル変数宣言］（５２１、５２２、５２３）、元々１つの関数だったものを複数に分けたことから、図３に示す元のソフトウエアプログラムの各処理（［初期化処理］（１０１）、［本体処理］（３０１）、［後処理］（４０１））間で値を受け渡した変数があれば、それはグローバル変数として定義する必要がある。それを宣言したのが［グローバル変数宣言２］（５１２）である。また、initializeとmain_calcは引数を定義しているが、ここではinitializeの処理内容はコマンド引数を利用しているものとし、変換後の上位のmain関数から引数を受け取る構成としている。また、繰り返し回数と直接関係する変数は繰り返しのための記述(for文など)の中で行い、その変数を［本体処理］（３０１）で利用するため、呼び出し元から引数として受け取る必要がある。
【００１９】
図５は、新たに記述する最上位のソースプログラムである。このソースプログラムでは、図４で定義した関数を呼び出す構成となっている。ここで、繰り返しのための記述（for文２０１、２０２）は下位の関数（main_calc）にそのまま残すのではなく、この最上位のソースプログラムに引き出しているのが最大の特徴であり、元のソースプログラムを単に３つに分けて関数化し、上位から改めて呼び出すようにしたのではない。
【００２０】
この構成変更は、元のソフトウエアプログラムの動作に実質的な影響を与えず、同じパラメータ、あるいは設定で計算を行えば、図３に示す元のソフトウエアプログラムで実行した場合と同じ結果が得られる。また、計算途中の状態を保存する処理の記載を下位の関数（main_calc）ではなく、図５に示す上位のソースプログラムのfor文の中に記述することにより、本体処理中ではなく、本体処理が終了した後に計算途中の状態を保存する。すなわち、特許文献２に記載されたシミュレーション装置のように、元のソフトウエアプログラムの下位関数などの内部は保存箇所とはせず、上位のソースプログラム内の記述であっても任意の箇所とはしない。
【００２１】
これにより、グローバル変数に対してのみ保存を行えば、汎用の計算機における保存・復元が可能となり、特に復元が一般的なソフトウエア技術のみで可能な環境を提供することができる。なお、繰り返し処理本体の１回の計算時間は通常数秒レベルであり、このような繰り返しのタイミングに保存・復元を限定した場合でもデバッグおよび当該ソフトウエアプログラムによる計算結果の取得作業の効率化に対してほぼ影響はない。
【００２２】
次に、計算途中の状態の保存方法について示す。ここでは、汎用の計算機に通常備わっているハードディスクドライブなどの記憶装置にファイルとして保存する場合について示す。
【００２３】
図６に、保存を実施するためのプログラム記述を図５の例に追加した例を示す。繰り返し回数を単純にカウントする変数：[繰返数]（２２１）の１００による剰余が９９になると保存を実施する（６０１）。この記述は、単純に１００回に１回の割合で保存するものである。このレートは、プログラム設計、デバッグ、テストなどを行う中で得られる大体の計算時間と、全体に要する計算時間から決定される。保存回数があまりに多ければ、ハードディスクドライブであっても使い切ってしまう可能性があり、また保存のための処理時間も計算時間に匹敵するようなものになってしまう可能性がある。そのため、計算機環境、デバッグなどの工程など、実施条件によってそれぞれ決定する。
【００２４】
次に、図６に示すソースプログラムを実行することにより行うメモリ１２への保存処理について図７に示すフローチャートを用いて説明する。なお、ここでは繰返数をｋ、繰返終了回数をＫとする。まず、初期化処理と繰返数ｋの初期化を行い（ステップＳＴ１０１）、パラメータの入力を行うソフトウエアプログラムであれば、入力手段１３によりパラメータの入力を行う（ステップＳＴ１０２）。次に、本体処理を実行し（ステップＳＴ１０３）、繰返数ｋが予め定められた保存を実施する回数（保存実施回数）である場合には（ステップＳＴ１０４）、保存先のファイルを開き（ステップＳＴ１０５）、グローバル変数の内容を保存して（ステップＳＴ１０６）、main_calcに与える引数の値を保存して（ステップＳＴ１０７）、そのファイルを閉じる（ステップＳＴ１０８）。ここで、ステップＳＴ１０４では、例えば、図６中の２２１に示すように（k % 100 == 99）といった計算式を用いたり、保存処理を行う繰返し数の間隔（保存実施間隔）を予め定めておき（k ％ 保存実施間隔 ＝ 0）といった計算式を用いたりすることができる。また、１回の計算でファイルは複数保存されるのが一般的な動作となるため、繰返数をファイル名に適用するなどして、ファイル名が重ならないようにする。また、一連のファイルを保存するディレクトリを用意する。繰返し数ｋが繰返し終了回数Ｋに達した場合は、後処理を行い（ステップＳＴ１１０）、プログラムの実行を終了する。繰返し数ｋが繰返し終了回数Ｋに達していない場合、ｋに１を加え（ステップＳＴ１１１）再度本体処理を実行する。
【００２５】
ここで、［グローバル変数保存処理］７０２（ステップＳＴ１０６）について詳しく述べる。保存対象のグローバル変数は、実体を直接参照する通常の変数および配列変数、およびポインタ変数に分けられる。それぞれ以下の処理を行う。
１．全てのグローバル変数（通常の変数、配列変数、ポインタ変数で共通）
変数の型、配列の場合はさらに要素数に従って、その領域をそれぞれバイナリ形式で保存する。ポインタ変数はポインタとしてのサイズを領域として保存する
２．ポインタ変数（ポインタ配列の要素、構造体内部のポインタを含む）
（ａ）固定サイズでメモリ確保を行った領域を参照しているものについては、当該領域をバイナリ形式で保存する。
（ｂ）また動的にサイズを指定してメモリ確保を行っているものについては、当該サイズを指定する元となった値が、基本的にグローバル変数として宣言されていることが期待できるため、それを利用して領域を計算し、バイナリ形式で保存する。
（ｃ）（ａ）および（ｂ）に該当しない変数は、他の実体のある変数を参照していることになる。順次以下の処理を行う。
（１）参照先が、１．のうち実体を直接参照している変数の実体のアドレス、および前記（ａ）および（ｂ）の変数の参照先と一致しないかどうかを確認する。一致していたらどの変数の実体に一致するかの記述を保存する。
（２）参照先が、１．のうち実体を直接参照している変数の実体のメモリ領域、および前記（ａ）および（ｂ）の変数が参照する領域に含まれるかどうかを確認し、含まれていたら基準となる変数と、参照先の相対位置を保存する。
（３）参照先が、他の全てのグローバル変数のアドレスに一致しないかどうかを確認し、一致した場合どの変数に一致するかの記述を保存する。
（４）参照先が特定できなかったものは、それがＮＵＬＬでないか、並びにスタック領域を参照していないかを確認し、どちらにも該当しないものは、変数の型に従った領域をバイナリで保存する。これは一般に存在しない。
（５）参照先がＮＵＬＬ、またはスタック領域と考えられるものは、全てＮＵＬＬとして保存する。
これで、基本的なグローバル変数の値と復元のための情報を保存することができる。
【００２６】
次に、保存した計算状態としてのグローバル変数を用いて、任意の復元ポイントで計算状態を復元する復元方法について説明する。図８に、復元してプログラムを再開するためのプログラム記述を図６に示すソースプログラムに追加した例を示す。図８に示すソースプログラムでは、ユーザにより復元ポイントが指定された場合、復元を実施する（６１１）。復元処理においては、指定された復元ポイントに対応する保存ファイルを開き（７１１）、読出復元処理（７１２，７１３）を行った後、読み出した保存ファイルを閉じ（７１４）、本体処理における繰返数の初期値を、７１３で読み出した値インクリメントした値に置き換える（７１５）。
【００２７】
また、繰り返し処理の前に指定した保存ファイルの内容を復元して、繰り返し処理を途中から開始する手順について、図９に示すフローチャートを用いて説明する。なお、繰返数をｋ、繰返終了回数をＫ、復元を行う繰返数（復元ポイント）をｎとする。復元ポイントは、ユーザが入力手段１３からパラメータを入力することにより指定する。まず、図７の場合と同様に、初期化処理と繰返数ｋの初期化を行い（ステップＳＴ２０１）、パラメータ入力（ステップＳＴ２０２）を行う。入力されたパラメータに復元を行う繰返数の指定があるかどうかを確認し（ステップＳＴ２０３）、なければそのまま初期化を反映して最初から計算を開始する。指定があれば、保存されたファイルのうち、復元を行う繰返数以下で、最も近い繰返し数に対応する保存ファイルを開き（ステップＳＴ２０４）、グローバル変数の内容を復元して（ステップＳＴ２０５）、main_calcに与える引数の初期値を取得し、最後に繰り返し処理の繰返数ｋの初期値を、読み出した値ｎに１を加えた値に置き換える（ステップＳＴ２０６）。その後繰り返し処理（ステップＳＴ２０７〜ＳＴ２１０）が行われるが、for文の繰返数の初期値が保存ファイルを生成したタイミングの次の値を示しているので、保存した直後からシミュレーションが再開されることになる。これにより、保存したタイミングまでの計算時間は不要となる。
【００２８】
図８において、［グローバル変数の読出復元処理］（７１２）で規定するグローバル変数の復元処理（ステップＳＴ２０５）について以下に示す。基本的に保存処理に対応した手順となる。
０．メモリ確保領域の開放
初期化処理の中でメモリ領域の確保を行い、グローバル変数で参照しているものは、確保したメモリを解放する。
１．全てのグローバル変数（通常の変数、配列変数、ポインタ変数で共通）
変数の型、配列の場合はさらに要素数に従って、そのサイズの領域にバイナリ形式で保存された値をロードする。
２．全てのポインタ変数(ポインタ配列の要素、構造体内部のポインタを含む)
（ｄ）前記保存処理の２．（ａ）および（ｂ）の変数について、該当するサイズのメモリ領域を確保し、そこへ保存ファイルにバイナリ形式で保存された内容をそれぞれロードする。
（ｅ）前記保存処理の２．（ａ）および（ｂ）に該当しない変数は、保存した際の条件にそれぞれ従って、以下の処理によって復元する。なお、以下の括弧付き番号は、前記保存処理の２．（ｃ）に記載した条件に合致したものにそれぞれ対応する。
（１）保存ファイルに示された参照先である変数の、現在の値（変数の実体のアドレス、あるいは前記（ｄ）のポインタ変数の値）をそれぞれ代入する。
（２）保存ファイルに示された参照先である領域の現在の値と、保存ファイルに示された相対位置から値（アドレス）を算出してそれぞれ代入する。
（３）保存ファイルに示された参照先の変数の現在のアドレスをそれぞれ代入する。
（４）変数の型に従ったサイズのメモリ確保を行ってそのメモリ領域を当該変数で参照し、さらにそのメモリ領域に保存ファイルの内容をそれぞれロードする。
（５）すべてＮＵＬＬ、つまり０を代入する。
【００２９】
なお、ソフトウエアプログラムの途中状態の保存・復元は、ここに記述した内容でいかなるプログラムにおいても対応できるわけではないが、プログラム内部での記述が変数の型に忠実であれば、上記対応をベースに保存・復元処理を記述することで対応可能である。いずれにしても、グローバル変数のみの保存・復元は、通常のソフトウエア技術で十分に可能である。また、プログラムの再開も本構成においては繰り返し数の指定だけで可能であり、簡単かつ確実にソフトウエアプログラムの途中状態を復元でき、再開を行うことができる。これでまず、一度計算を実施した後、結果を見て、再度計算を実施して詳細情報を抽出したり、デバッグをしたりするときに、最初から計算をやり直すのではなく、確認したいタイミングより前でかつ最も近いタイミングで保存された途中経過保存ファイル(以下で、スナップショットとする)を使用してそこから計算を再開することで、最初から計算した場合にそのタイミングに達するまでに必要な計算時間を節約することができる。
【００３０】
また、市販、あるいはオープンソースのプログラムデバッガを用いてデバッグを行う場合について示す。プログラムデバッガを用いる場合の計算処理装置では、以下の段階を踏むことになる。
１．途中経過状況保存を実施するように設定して全体の計算を行い、結果を確認して、期待されない動作が行われていることを認識する。
２．概略のログ表示を確認し、大体の異常発生時刻を特定する。
３．途中経過状況保存をより高頻度に、またログをより詳細にして、発生直前の途中経過保存ファイルを利用して計算を再開する。
４．異常発生時刻を経過してから計算を止め、詳細ログから異常発生を再度確認する。
５．デバッガ上でプログラムを起動し、異常発生時刻に最も近い途中経過保存ファイルを利用して、そこからプログラムを再開して、プログラム記述レベルのデバッグを進める。
これにより、異常発生まで何度でも短い時間で達することができ、デバッグ効率をさらに向上させることができる。
【００３１】
再開を矛盾なく行うためには、［本体処理］（３０１）に変更を加えてコンパイルすることはできないが、追加した最上位のソースプログラムは変更することができる。このため、最上位のソースプログラムの修正を行った場合でも、途中から計算を再開することができ、デバッグまたは再処理の作業効率を向上させることができる。また、［本体処理］（３０１）はこの上位プログラムで参照可能なグローバル変数を使用しているので、復元直後、あるいは異常発生の前後など、繰り返し処理の合間にグローバル変数の値を変更することは任意である。
【００３２】
この特徴を利用して、最初に長時間の計算を行う時には取得しきれなかった変数、あるいは変数の詳細情報を取得して、デバッグ、あるいは評価を行うためのプログラム記述例を図１０に示す。図１０では、図８における途中経過の復元処理（６１１、７１１〜７１５の処理）をまとめて［途中経過復元処理］（６１１、７１１〜７１）としている。一般にシミュレーションなどで対象の評価を行うときは、パラメータや設定をいくつかのパタンで用意し、昼夜を問わず連続的に計算を行わせて、後でそれら全ての結果を確認するという作業の流れが一般的である。そのため通常保存するログやデータは、必要最低限に抑える。よって、異常発生は認識できても、原因を特定するまでの情報はその時点では取得できていないのが一般的である。
【００３３】
そこで、図１０では、異常発生が"繰返数"で１５４２２３のタイミングだったとして、その前後の繰返数（１５４２１１〜１５４２３０）において、より詳細な情報を取得するために、［変数の内容を表示］（７２１）、［プログラムトレースの表示］（７２２）、［変数の内容をファイルに保存］（７２３）を追加している。ここで、図１０の［変数の内容を表示］（７２１）および［変数の内容をファイルに保存］（７２３）における"変数"とはグローバル変数である。特にこれは、グローバル変数の内容を参照して、表示または保存処理をしているだけであるので、変数値の変更等をしているものではなく、main_calc関数の処理に影響はない。また、途中経過の復元・再開も最初の計算で取得したスナップショットを用いて問題なく復元可能である。
【００３４】
また、［プログラムトレースの表示］（７２２）のように処理の詳細を表示するプログラムトレース機能などを用意しておくと、バグの種類によってはこれだけで原因が特定でき、デバッガを用いなくとも原因の特定を行うことができる場合がある。これは、異常を認識してもいない最初の計算実施の段階で適用した場合、大量の表示を行い、表示を保存するだけで相当のＣＰＵタイムを奪ってしまうため、詳細な情報を取得する段階で適用する。なお再計算する際には、スナップショットの保存頻度を上げることにより、より作業効率を上げることができる。ただし、目的のタイミングに達するまで１分程度になれば十分と考えられる。
【００３５】
更にグローバル変数を変化させながらデバッグ、あるいは評価を進めるためのプログラム記述例を図１１に示す。ここでは、異常発生のタイミングである１５４２２３におけるプログラム本体(main_calc)の計算の前に、２つのグローバル変数の値を変更してする処理［グローバル変数Ａの値をｘ１に変更］（７３１）、［グローバル変数Ｂの値をｘ２に変更］（７３２）を追加している。また、続く１５４２２４のタイミングにおいても、グローバル変数の値を変更する処理［グローバル変数Ａの値をｘ３に変更］（７３３）、［グローバル変数Ｂの値をｘ４に変更］（７３４）を追加している。このように値を変化させ、明示的に"元のソフトウエアプログラム([本体処理])"の動作に影響を与え、結果を確認することも可能である。この程度の変数の変更であればデバッガを利用しても簡単に行えるが、より多くの変数の変更を、更には一定のパタン、あるいはファイルに記述した内容で行う場合には、プログラム記述で実施できることは極めて有効である。そうした場合のプログラム記述例を図１２に示す。なお、各処理とmain_calcの位置関係は目的に応じて決めればよく、当然この限りではない。図１２では、繰り返し処理の前で"繰返数"毎にグローバル変数に適用すべき値をリストアップした変数値定義ファイルをオープンし(７４１)、繰り返し処理の中で、"繰返数"が一定の条件になったらグローバル変数の変更を開始する(６４１)。グローバル変数の変更のための記述は、変数名と値(バイナリ)のセットを各繰返数毎に読み出して、順次適用する(７４２、７４３)。"繰返数"が一致しなければ適用しないなどの手順を入れるとより使いやすくなる。そして繰り返し処理を抜けてから、ファイルをクローズする(７４４)。
【００３６】
実施の形態１に係る計算処理装置では、以上のような構成をしているため、専用装置を用いる必要がなく、こうした効率的なデバッグ等の実施手段を各種の広範なソフトウエアプログラムに適用することができる。また、各処理を関数として独立して定義することにより、一部の関数を修正して再計算する場合でも、別の関数やその上位のソースプログラムに関しては修正を行う必要がなく、ソースファイルの管理やコンパイルなどの作業が容易となり、作業効率を向上させることができる。また、保存を繰返し処理の度ではなく、一定の間隔ごとに行うことにより、計算状態の保存に必要な容量を減らすことができ、保存した計算状態から再実行することにより、効率的に計算状態の復元を行うことができる。また、グローバル変数をその特性に応じて保存方法を変えることにより、ポインタ変数等を用いた場合においても矛盾なく計算状態の復元を行うことができる。
【００３７】
実施の形態２．
実施の形態１では、古典的なＣ言語など、オブジェクト指向プログラミングではない言語での適用について示してきたが、実施の形態２ではオブジェクト指向言語、特に近年広く適用されているＪａｖａ（登録商標）を用いた場合について示す。実施の形態２に係る計算処理装置の構成は図１と同様であり、基本的な状態保存手順および状態復元手順を表すフローチャートは図７、図９と同様である。以下では、図１に示す計算処理装置に実行させるソフトウエアプログラムの記述方法について述べる。
【００３８】
オブジェクト指向言語においても、デバッグや再評価の対象となるソフトウエアプログラムの基本構成は実施の形態１の場合と同様である。また、新たに記述する最上位のソースプログラムについては図３の記述と基本は同じであるが、図１３に示すように、オブジェクト(クラス)を規定する記述で囲まれる(００１、００２)。また、関数をメソッドと呼ぶのが一般的であり、グローバル変数に相当するものは各クラスの中に定義され(５５１)、フィールドなどと呼ばれる。
【００３９】
次に、元のソフトウエアプログラムの各処理をオブジェクトとして関数化したソースプログラムの記述例を図１４に示す。関数化については図４と同じであるが、クラスを規定する記述(００１、００２)、およびグローバル変数をフィールドとしている(５５１、５５２)点が異なる。また初期化を行うinitializeは、このままメソッドとしても良いが、ここでは、オブジェクトを構築するコンストラクタとして記述している(２５１)。コンストラクタはオブジェクト(クラス)名称と同じ名前を指定する。またコンストラクタに与える引数についても図４と同様で、コマンド引数をそのまま与えることになる。ここでも他のメソッド(main_calcまたはfinishing)でコマンド引数を参照する必要があれば、新たなフィールドを宣言しておいてそこにコマンド引数を保存しておくなどの対応を行う。
【００４０】
そして、最上位のソースプログラムとして新たに記述するソースプログラムを図１５に示す。これもクラスを示すための記述(０１１、０１２)が追加されている他は、プログラムの構成としては図５と特に変わらない。ただし、"元のソフトウエアプログラム"は記述上も本質的にオブジェクトとなり、オブジェクトとして実体(インスタンス)が宣言され、そこでまず初期化が行われるが、初期化にあたり、コマンド引数をそのまま引数として与えている（８０１）。そして繰り返し処理本体の計算、および後処理においても、メソッドの呼び出しとして記述がそれぞれ適用されている（８０２、８０３)。
【００４１】
ここで、途中経過保存、および復元のための処理を追加した記述例を図１６に示す。基本構成は図８と特に変わらないが、オブジェクト指向言語、特にＪａｖａ（登録商標）においては保存・復元処理が簡単になる。なお、図８では、initializeの呼び出しを無条件で行った後、指定保存ファイルの有無を確認していたが、図１６の例では、if〜elseのelseに記述して、処理が重ならないようにしている。図８のように無条件で呼び出してから上書きしても問題はない。
【００４２】
記述する上で図８と異なる点を、それぞれ以下に示す。
１．オブジェクト復元処理(７５２)
オブジェクト(クラス)の内容をファイルから読み出し復元して、元のソフトウエアオブジェクトを示す変数ａに代入する。図８の例では、グローバル変数を回復するのが主な処理であったが、オブジェクト指向言語では、記述上、フィールドの他にプログラムそのものもここで回復させることとなる。実際には、プログラムを含め、動作中変更されることのないものはコンパイル時に生成されたクラスファイルから参照され、変更可能なフィールドが保存ファイルから回復されるのが一般的である。
２．変数ａ参照のオブジェクトの書出(７５７)
オブジェクト(クラス)の内容、特に変更可能なフィールドをファイルに書き出す。上記のオブジェクトの読み書き処理は、特にＪａｖａ（登録商標）言語では直列化機能として実装されていて、そのためには、保存対象のクラスのソースプログラムにおける宣言で、この直列化機能を実装するよう記述を追加するだけである。図１５の０１１に、"implements Serializable"を追加するだけである。その内容を図１７に示す。ただし、この"SimTop"以下で利用され、保存の対象となる全てのクラスにおいてこの宣言がなされている必要がある。
【００４３】
ここで、図１６の例では、オブジェクトの他に繰返数の保存・復元を行う必要があるが、前記オブジェクトの保存ファイルは、専用の手順によって生成されるので、オブジェクト保存専用のファイルとするのが適当である。そこで、繰返数の保存(７５８)・復元(７５３)においては、以下のような実装方法が考えられる。
３．専用のファイルを別途用意
オブジェクトを保存したファイル名から拡張子を変えるなどしたファイルを用意し、保存、復元を行う。
４．ファイル名に入れ込む
オブジェクトを保存するファイル名に、一定の桁数の領域を設けて、そこに値を記述する。[main_calc引数の保存処理]（７５８）は括弧で囲んでいるが、この方法を適用した場合は、[新規ファイルのオープン](７５６)の時点で保存は完了していると言うことができる。
いずれにおいても、特に問題なく実装可能な方法である。
【００４４】
なお、元のソフトウエアプログラムが、本体の計算中にずっとファイルを開いたままにしておき、継続して読み出す、あるいは書き込むなどを行う場合、オブジェクトの直列化機能を利用する場合においても一定の手順が必要になる。これらのファイルの準備に関する手順である。オブジェクト指向言語においても、ファイルの入出力を行うオブジェクトは直列化することができないため、以下の処理を行う。また、そのプログラム記述例を図１８に示す。
１．保存
保存処理の前に、その時点のファイルポインタの位置を読み出し（７６３）、ファイルをクローズし（７６４）、ファイルの入出力オブジェクトを参照している変数にはｎｕｌｌを入力する。途中経過の保存処理においてはファイルポインタの位置も併せて保存する。またその後、処理を継続するために、再度閉じたファイルをオープンし（７６５）、ファイルポインタを閉じた時点の位置にそれぞれ移動させる（７６６）。なお、ファイルポインタ位置について、設定はできるが、読み出しはできないのが一般的であると考えられる。できない場合には、読み出し位置を示すグローバル変数、あるいはフィールドを用意し、何文字（何バイト）のデータを読み出したかなどを常に把握しておくようなプログラム記述が必要になる。
２．復元
復元処理の後に、必要なファイルをオープンし（７６１）、ポインタ位置を保存ファイルから取得して、対応する各ファイルのファイルポインタ位置を移動させる（７６２）。なお、書き込みファイルの場合は、オープンの時に追加モードでファイルを開けば良い場合が多いと考えられる。なお、必要なファイルのオープンにはそのファイルの所在（ファイル名）が必須である。そこで、グローバル変数、あるいはそのファイルを利用するオブジェクトのフィールドとして、ファイル名が保存されていなければならない。必要に応じ、プログラム記述を追加する。  
【００４５】
ポインタの保存に当たっては、別途ファイルを用意するか、グローバル変数として、あるいは元のソフトウエアプログラムのフィールドとして保存する。基本的に元のソフトウエアプログラムは変更しないのが望ましいが、グローバル変数、あるいはフィールドを追加し、最上位から読み書きするだけであれば本来の機能に影響を与えないで実施可能である。
【００４６】
次に、一部のオブジェクトを、プログラム記述を変更してコンパイルしたものに置き換えてから計算を行う場合について示す。特にオブジェクト指向プログラミングにおいては、プログラム自体を変更させることも容易である。元のソフトウエアオブジェクトをすべて変えるのではなく、変更の対象は一部の機能（オブジェクト）である。特にデバッグなどで修正を確認する際、現象が起きる直前で、フィールドを引き継いだ上で修正したオブジェクトに置き換え、計算を継続させることで修正が確認できる場合がある。この場合、あくまでも修正前のオブジェクトを継承した別の名称のオブジェクトとして、必要な箇所を変更するようにする。そうすることで、一度元のオブジェクトで復元された後で、修正オブジェクトに置換することが可能となる。
【００４７】
その変更手順のプログラム記述例を図１９に示す。図１９において各処理の内容は以下のとおりである。
１．置換タイミング条件の確認（６４１）
繰返数によって事象発生タイミングを捉える。
２．修正オブジェクトのインスタンスの宣言（７７１）
修正した新しいオブジェクトのインスタンスを宣言（初期化）する。
３．フィールドの引き継ぎ（７７２）
修正前後で共通のフィールドについて、あるいはデバッグ等において必要なフィールドについて、修正後のオブジェクトに元のオブジェクトの値を反映させる。また必要に応じ、フィールドを変更する。
４．オブジェクトの置換（７７３）
修正後、フィールド引き継ぎ後のオブジェクトで、元のオブジェクトを置き換える。
これで時間的にもっとも効率よく対象の事象を発生させ、修正後のオブジェクトでの動作を確認することが可能となる。
【００４８】
次に、繰り返し処理が、時間離散型シミュレーションプログラムの記述において広く適用されている、イベントキューからイベント情報を読み出すことから始まるプログラムでの実施例を示す。当該プログラムの処理フローを図２０に示す。図２と構成はほとんど同じであるが、イベントキューからイベント情報を読み出すことから繰り返し処理の中身が開始される（３６２）。一般に、このイベント情報はイベントの内容、発生箇所などのデータをまとめたオブジェクトで、当該イベントがいつ発生するかを示すシミュレーション上の時刻情報を伴い、新たにキューに保存されるイベント情報は常にこの時刻情報に基づいて昇順に並べ替えられる。したがって、キューからは時刻順に常に読み出される。シミュレーション処理の本体は、読み出されたイベント情報に従って、処理時刻を設定し、そのイベントの発生箇所（オブジェクト）、発生内容に従って処理を行う（３６１）。こうして、シミュレーションが進行する。
【００４９】
図２１に、この場合の最上位のプログラム記述例を示す。キューそのものは元のソフトウエアプログラムの一部であることが一般的であるため、オブジェクト指向言語であれば、途中経過保存処理（７８６）および復元処理（７８１）において、繰り返し処理回数（図１９における"繰返数"）を別途保存する必要もなく、キューの待ち行列も含めて全て保存ファイルに書き出され、また復元が可能である。よって、保存・復元処理のプログラム記述は、保存処理では図１９における[main_calc引数の保存処理]（７５８）、復元処理では図１９の[main_calc引数の読出復元処理]（７５３）が削除されている。
【００５０】
また、途中経過保存のタイミングも、繰り返し処理回数ではなく、シミュレーション上の時刻で指定することが可能となる。これを実装するプログラム記述例が図２１の６８１の繰り返し処理である。例えば、計算終了までに１０回保存するとして、終了時刻がシミュレーション上の時刻で１秒だとすると、interval＝0.1として、新規イベント情報(オブジェクト)の生成（７８１）、イベント時刻の設定（７８２）、イベント種別の設定（７８３）、そしてキューへのイベント情報の登録（７８４）の各処理を１０回行うことで、各保存時刻に保存イベントが読み出されるための準備が完了する。厳密には、１０回目は計算終了時刻となり、途中経過保存の必要性は通常ない。
【００５１】
繰り返し処理の記述は、"while(true)"で始まる無限ループとなる（２９１）。このループの中で、キューからイベント情報を読み出す度にイベント時刻を確認し、終了時刻よりも後の時刻を検出したら、そこでwhileを抜け、計算終了となる（６８２）。そして経過保存処理は、イベント種別が経過保存実施に一致すると行われ（６８３）、これでシミュレーション上の時間で０．１秒毎に途中経過が保存される。また計算の本体はこれまで通り呼び出すが、引数は、図１９までの例では必須であった"繰返数"はなく、代わりにイベント情報（オブジェクト）が必須の引数となる（３８１）。
【００５２】
実施の形態２に係る計算処理装置では、以上のように記述したソフトウエアプログラムを実行することにより、オブジェクト指向プログラミングを用いた場合でも実施の形態１と同様の効果が得られる。なお、繰り返し処理がないものでも、一連の処理を複数のメソッドに分けることによって同様の効果が得られる。また、ここではオブジェクト指向プログラムとしてＪａｖａ（登録商標）を用いた場合について示したが、これに限られるものではなく、その他のオブジェクト指向言語を用いた場合でも同様の効果が得られる。
【符号の説明】
【００５３】
１１  プログラム実行手段、１２  メモリ、１３  入力手段、１４  表示装置
【図１】
0005447273.tif 000002
【図２】
0005447273.tif 000003
【図３】
0005447273.tif 000004
【図４】
0005447273.tif 000005
【図５】
0005447273.tif 000006
【図６】
0005447273.tif 000007
【図７】
0005447273.tif 000008
【図８】
0005447273.tif 000009
【図９】
0005447273.tif 000010
【図１０】
0005447273.tif 000011
【図１１】
0005447273.tif 000012
【図１２】
0005447273.tif 000013
【図１３】
0005447273.tif 000014
【図１４】
0005447273.tif 000015
【図１５】
0005447273.tif 000016
【図１６】
0005447273.tif 000017
【図１７】
0005447273.tif 000018
【図１８】
0005447273.tif 000019
【図１９】
0005447273.tif 000020
【図２０】
0005447273.tif 000021
【図２１】
0005447273.tif 000022