説明

計算処理方法、計算処理装置およびソフトウエアプログラム

【課題】
計算時間の大半を繰り返し処理が占めるソフトウエアプログラムのデバッグや、当該プログラムを利用して計算結果を得るまでの作業効率を向上させる。
【解決手段】
この発明に係る計算処理方法は、演算プログラムを複数回繰返し実行する繰返実行ステップ(ST103)と、予め定められた回数繰返し実行した場合に、予め定められた回数だけ実行が終了した時の計算状態を保存する状態保存ステップ(ST106)、を備える第1の演算ステップと、状態保存ステップで保存された計算状態のうち、指定された復元ポイントに近い繰返し回数における保存された計算状態を選択して読み出す選択読出ステップ、前記選択された計算状態に基づいて、演算プログラムを実行する復元ステップ、を備える第2の演算ステップと、を備えている。

【発明の詳細な説明】
【技術分野】
【0001】
本発明は、例えばデバッグを伴うシミュレーションなどを行う計算処理方法、計算処理装置およびソフトウエアプログラムに関する。
【背景技術】
【0002】
ソフトウエアプログラムを計算機上に適用し、繰返し処理を含む計算を長時間行って得た結果を利用することは多くの分野で行われている。天気予報などはその典型的な例といえる。これらの計算時間については、一瞬で終わるものから数日、あるいはそれ以上かかるものなど様々である。こうしたソフトウエアの開発にあたり、ソフトウエア試験および修正を行い、目的である現象等の評価段階、つまりソフトウエアプログラムを本格的に利用する段階になって、長時間の繰返し計算を行ったところ、これまで出ていなかったソフトウエアの問題(バグ)が見つかることがある。それは多くの場合、長時間の繰返し計算を行うことで、ソフトウエア試験ではカバーしきれなかった事象が発生するためである。
【0003】
このような場合、ソフトウエアプログラムのデバッグ作業を行い、不具合箇所を発見し、修正する作業を行う必要がある。ソフトウエアプログラムのデバッグを行うには、問題の起きた前後のタイミングで詳細な情報収集を行うため設定を行い、ソフトウエアプログラムを最初から再度長時間の計算を行う必要がある。1回のやり直しで原因がわかり、解決することは稀であり、たとえ1回のやり直しで解決できたとしても、数時間、あるいは数日に及ぶような計算をもう一度実施しなければならず、多くの時間を消費してしまうことになる。したがって、デバッグ作業の効率化はソフトウエア開発を行う上で必要不可欠となる。
【0004】
デバッグ作業の効率化のため、次のような提案がなされている。特許文献1には、計算プログラムに与える各種のパラメータを、前回の計算結果に基づいて効果的な値になるよう支援するシミュレーション装置が記載されている。このパラメータ設定の手間を減らし、また効果的なパラメータ設定ができれば、評価の回数を減らすことができ、予定よりも短い日数で、所定の結果を得ることができる。また、特許文献2には、プログラムソースの内容から、計算途中の保存に必要なメモリ容量を見積もり、そして計算中、可能な範囲で途中の状況をメモリに保存しておき、保存した時点から計算を再開できるようにすることで、デバッグの時間効率を上げるシミュレーション装置が記載されている。
【先行技術文献】
【特許文献】
【0005】
【特許文献1】特開2006−146369号公報(第5頁〜第11頁、図1)
【特許文献2】特開2006−172102号公報(第3頁、図1)
【発明の概要】
【発明が解決しようとする課題】
【0006】
しかしながら、従来のシミュレーション装置ではそれぞれ以下に示すような問題がある。特許文献1に記載のシミュレーション装置では、パラメータを効果的に設定することにより、評価を進める上で計算回数を減らし、目的の効果が得られるまでの時間が短縮されることが考えられるが、繰り返し最初から最後までソフトウエアプログラムを実行する必要があり、例えば、1回の計算に10時間かかるソフトウエアプログラムにおいては、次の計算にも10時間を要し、デバッグ作業を行うにあたっては最初から計算しなおして長時間待機しなければならない。
【0007】
また、特許文献2に記載のシミュレーション装置を用いて繰返し処理を含むソフトウエアプログラムを計算機上に適用し、長時間計算して結果を得て利用するような場合には次のような問題点がある。デバッグのためにプログラムの修正を行った場合、再度コンパイルおよび実行を行う必要があり、長時間の計算を行う必要がある。また、あらかじめ保存に必要なメモリをプログラムソースから算出しており、各保存箇所における保存量をあらかじめ決めているため、シミュレーションに与えるパラメータや初期設定によってプログラム上の同一の箇所(保存箇所)においてメモリ使用量が変化することは許容されず、繰返し処理の度に使用メモリが変化するようなシミュレーションなどでは多くの場合適用できず、汎用的でないという問題がある。
【0008】
この発明は、上記のような課題を解決するためになされたもので、ソフトウエアプログラムのデバッグ処理の作業効率および汎用性の向上を目的とする。
【課題を解決するための手段】
【0009】
この発明に係る計算処理方法は、第1の演算プログラムおよび第2の演算プログラムを有するソフトウエアプログラムを実行する計算処理方法であって、前記第1の演算プログラムを実行する演算実行ステップ、前記第1の演算プログラムとは独立してその内容が規定された前記第2の演算プログラムを、複数回繰返し実行する繰返実行ステップ、前記繰返実行ステップにおいて、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存ステップ、を備える第1の演算ステップと、前記ソフトウエアプログラムの修正要否に応じて、前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定する復元ポイント指定ステップ、前記状態保存ステップで保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出ステップ、前記選択された計算状態に基づいて、前記第2の演算プログラムを実行する復元ステップ、を備える第2の演算ステップと、を備える。
【0010】
また、この発明に係るソフトウエアプログラムでは、計算機に、第1の演算プログラムを実行する演算実行ステップ、前記第1の演算プログラムとは独立してその処理内容が規定された第2の演算プログラムを、複数回繰返し実行する繰返実行ステップ、前記繰返実行ステップにおいて、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存ステップ、を備える第1の演算手順と、前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定させる復元ポイント指定ステップ、前記状態保存ステップで保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出ステップ、前記選択された計算状態に基づいて、前記第2の演算プログラムを実行する復元ステップ、を備える第2の演算手順と、を実行させる。
【0011】
また、この発明にかかる計算処理装置では、第1の演算プログラムおよび第2の演算プログラムを有するソフトウエアプログラムを実行する計算装置であって、前記第1の演算プログラムを実行する演算実行手段と、前記第1の演算プログラムとは独立してその処理内容が規定された前記第2の演算プログラムを、複数回繰返し実行する繰返実行手段と、前記繰返実行手段において、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存手段と、前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定する復元ポイント指定手段と、前記状態保存手段で保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出手段と、前記選択読出手段で選択された計算状態に基づいて、前記第2の演算プログラムを実行する復元手段と、を備える。
【発明の効果】
【0012】
この発明によれば、ソフトウエアプログラムのデバッグ処理の作業効率を向上させ、また、汎用性を向上させることができる。
【図面の簡単な説明】
【0013】
【図1】本発明の実施の形態1に示す計算処理装置の構成を示すブロック図である。
【図2】本発明の実施の形態1に示す計算処理装置における処理の対象となるソフトウエアプログラムの基本構成のフローチャートである。
【図3】本発明の実施の形態1に示すソースプログラムの例を示す図である。
【図4】本発明の実施の形態1に示すソースプログラムの例を示す図である。
【図5】本発明の実施の形態1に示すソースプログラムの例を示す図である。
【図6】本発明の実施の形態1に示すソースプログラムの例を示す図である。
【図7】本発明の実施の形態1に示すソフトウエアプログラムのフローチャートを示す図である。
【図8】本発明の実施の形態1に示すソースプログラムの例を示す図である。
【図9】本発明の実施の形態1に示すソフトウエアプログラムのフローチャートを示す図である。
【図10】本発明の実施の形態1に示すソースプログラムの例を示す図である。
【図11】本発明の実施の形態1に示すソースプログラムの例を示す図である。
【図12】本発明の実施の形態1に示すソースプログラムの例を示す図である。
【図13】本発明の実施の形態2に示すソースプログラムの例を示す図である。
【図14】本発明の実施の形態2に示すソースプログラムの例を示す図である。
【図15】本発明の実施の形態2に示すソースプログラムの例を示す図である。
【図16】本発明の実施の形態2に示すソースプログラムの例を示す図である。
【図17】本発明の実施の形態2に示すソースプログラムの例を示す図である。
【図18】本発明の実施の形態2に示すソースプログラムの例を示す図である。
【図19】本発明の実施の形態2に示すソースプログラムの例を示す図である。
【図20】本発明の実施の形態2に示すソフトウエアプログラムのフローチャートをソースプログラムの例を示す図である。
【図21】本発明の実施の形態2に示すソースプログラムの例を示す図である。
【発明を実施するための形態】
【0014】
実施の形態1.
図1は、本発明の実施の形態1に係る計算処理装置の構成を示すブロック図である。図において、プログラム実行手段11は、ソフトウエアプログラムの実行等を行う。メモリ12は、ソフトウエアプログラムの途中の計算状態および計算結果を保存する。ここではハードディスクドライブを用いる。入力手段13はソフトウエアプログラムの入力およびパラメータ値の入力を行う。表示装置14は、プログラム実行手段11により出力される出力結果、パラメータ値等を表示する。
【0015】
実施の形態1に係る計算処理装置では、その中に繰り返し演算を含むソフトウエアプログラムの実行、デバッグ等の処理を行う。対象となるソフトウエアプログラムの基本構成のフローチャートを図2に示す。図3に、その動作が図2のフローチャートで表されるソフトウエアプログラムのソースプログラムのうち、最上位にくる記述の簡単な例を示す。なお、ここでは古典的なC言語など、オブジェクト指向プログラミングではない言語を用いて適用した場合について示す。図3において、[ ]で示したものはソースプログラムに記載される処理の内容を示しており、他の図においても同様である。図3に示すソースプログラムには、main関数と[グローバル変数宣言](511)が記述されており、[グローバル変数宣言](511)では、main関数から直接、あるいは下位の各関数で共通に参照可能なグローバル変数を記述する。また、main関数には、[ローカル変数の宣言](501)、[初期化処理](101)、繰り返し処理(201、202)の内部に配置された計算の[本体処理](301)、[後処理](401)が記述される。図3に示すソースプログラムではmain関数に[本体処理](301)を記述する構成としているが、main関数に下位に関数を新たに記述し、本体処理の全部または一部をこの関数の中に記述することも可能であるが、記述上の問題だけであり、ソフトウエアプログラムの動作・構成には影響がない。
【0016】
このソースプログラムを以下に示すように記述し直すことにより、専用装置を必要とせず汎用的な計算機により実施の形態1に係る計算処理装置を実現することができる。図4に新たに定義するソースプログラムの概略を示す。
【0017】
図3に示したソースプログラム(以下で、元のソースプログラムとする)の本体処理等の各処理について、それぞれの処理内容を独立して規定してプログラム実行手段11に実行させるようにする。すなわち、図4に示すように、各処理を以下のオブジェクト(ここでは関数)として定義し、これらをさらに図5に示すように上位のソースプログラムで呼び出す構成とする。図4では、以下の関数を定義している。
1.initialize(コマンド引数)
元のソースプログラムの初期化処理を含む。必要に応じコマンド引数をそのまま引数として受け取る。
2.main_calc(引数)
元のソースプログラムの繰り返し処理の本体処理(繰返し処理における1回分の処理)を含む。引数には繰返し処理の繰り返し数を含む。
3.finishing
元のソースプログラムの後処理を含む。例えば、結果の出力処理などを規定する。
【0018】
各処理を関数化したことで、それぞれの関数の中でローカル変数を宣言しているほか[ローカル変数宣言](521、522、523)、元々1つの関数だったものを複数に分けたことから、図3に示す元のソフトウエアプログラムの各処理([初期化処理](101)、[本体処理](301)、[後処理](401))間で値を受け渡した変数があれば、それはグローバル変数として定義する必要がある。それを宣言したのが[グローバル変数宣言2](512)である。また、initializeとmain_calcは引数を定義しているが、ここではinitializeの処理内容はコマンド引数を利用しているものとし、変換後の上位のmain関数から引数を受け取る構成としている。また、繰り返し回数と直接関係する変数は繰り返しのための記述(for文など)の中で行い、その変数を[本体処理](301)で利用するため、呼び出し元から引数として受け取る必要がある。
【0019】
図5は、新たに記述する最上位のソースプログラムである。このソースプログラムでは、図4で定義した関数を呼び出す構成となっている。ここで、繰り返しのための記述(for文201、202)は下位の関数(main_calc)にそのまま残すのではなく、この最上位のソースプログラムに引き出しているのが最大の特徴であり、元のソースプログラムを単に3つに分けて関数化し、上位から改めて呼び出すようにしたのではない。
【0020】
この構成変更は、元のソフトウエアプログラムの動作に実質的な影響を与えず、同じパラメータ、あるいは設定で計算を行えば、図3に示す元のソフトウエアプログラムで実行した場合と同じ結果が得られる。また、計算途中の状態を保存する処理の記載を下位の関数(main_calc)ではなく、図5に示す上位のソースプログラムのfor文の中に記述することにより、本体処理中ではなく、本体処理が終了した後に計算途中の状態を保存する。すなわち、特許文献2に記載されたシミュレーション装置のように、元のソフトウエアプログラムの下位関数などの内部は保存箇所とはせず、上位のソースプログラム内の記述であっても任意の箇所とはしない。
【0021】
これにより、グローバル変数に対してのみ保存を行えば、汎用の計算機における保存・復元が可能となり、特に復元が一般的なソフトウエア技術のみで可能な環境を提供することができる。なお、繰り返し処理本体の1回の計算時間は通常数秒レベルであり、このような繰り返しのタイミングに保存・復元を限定した場合でもデバッグおよび当該ソフトウエアプログラムによる計算結果の取得作業の効率化に対してほぼ影響はない。
【0022】
次に、計算途中の状態の保存方法について示す。ここでは、汎用の計算機に通常備わっているハードディスクドライブなどの記憶装置にファイルとして保存する場合について示す。
【0023】
図6に、保存を実施するためのプログラム記述を図5の例に追加した例を示す。繰り返し回数を単純にカウントする変数:[繰返数](221)の100による剰余が99になると保存を実施する(601)。この記述は、単純に100回に1回の割合で保存するものである。このレートは、プログラム設計、デバッグ、テストなどを行う中で得られる大体の計算時間と、全体に要する計算時間から決定される。保存回数があまりに多ければ、ハードディスクドライブであっても使い切ってしまう可能性があり、また保存のための処理時間も計算時間に匹敵するようなものになってしまう可能性がある。そのため、計算機環境、デバッグなどの工程など、実施条件によってそれぞれ決定する。
【0024】
次に、図6に示すソースプログラムを実行することにより行うメモリ12への保存処理について図7に示すフローチャートを用いて説明する。なお、ここでは繰返数をk、繰返終了回数をKとする。まず、初期化処理と繰返数kの初期化を行い(ステップST101)、パラメータの入力を行うソフトウエアプログラムであれば、入力手段13によりパラメータの入力を行う(ステップST102)。次に、本体処理を実行し(ステップST103)、繰返数kが予め定められた保存を実施する回数(保存実施回数)である場合には(ステップST104)、保存先のファイルを開き(ステップST105)、グローバル変数の内容を保存して(ステップST106)、main_calcに与える引数の値を保存して(ステップST107)、そのファイルを閉じる(ステップST108)。ここで、ステップST104では、例えば、図6中の221に示すように(k % 100 == 99)といった計算式を用いたり、保存処理を行う繰返し数の間隔(保存実施間隔)を予め定めておき(k % 保存実施間隔 = 0)といった計算式を用いたりすることができる。また、1回の計算でファイルは複数保存されるのが一般的な動作となるため、繰返数をファイル名に適用するなどして、ファイル名が重ならないようにする。また、一連のファイルを保存するディレクトリを用意する。繰返し数kが繰返し終了回数Kに達した場合は、後処理を行い(ステップST110)、プログラムの実行を終了する。繰返し数kが繰返し終了回数Kに達していない場合、kに1を加え(ステップST111)再度本体処理を実行する。
【0025】
ここで、[グローバル変数保存処理]702(ステップST106)について詳しく述べる。保存対象のグローバル変数は、実体を直接参照する通常の変数および配列変数、およびポインタ変数に分けられる。それぞれ以下の処理を行う。
1.全てのグローバル変数(通常の変数、配列変数、ポインタ変数で共通)
変数の型、配列の場合はさらに要素数に従って、その領域をそれぞれバイナリ形式で保存する。ポインタ変数はポインタとしてのサイズを領域として保存する
2.ポインタ変数(ポインタ配列の要素、構造体内部のポインタを含む)
(a)固定サイズでメモリ確保を行った領域を参照しているものについては、当該領域をバイナリ形式で保存する。
(b)また動的にサイズを指定してメモリ確保を行っているものについては、当該サイズを指定する元となった値が、基本的にグローバル変数として宣言されていることが期待できるため、それを利用して領域を計算し、バイナリ形式で保存する。
(c)(a)および(b)に該当しない変数は、他の実体のある変数を参照していることになる。順次以下の処理を行う。
(1)参照先が、1.のうち実体を直接参照している変数の実体のアドレス、および前記(a)および(b)の変数の参照先と一致しないかどうかを確認する。一致していたらどの変数の実体に一致するかの記述を保存する。
(2)参照先が、1.のうち実体を直接参照している変数の実体のメモリ領域、および前記(a)および(b)の変数が参照する領域に含まれるかどうかを確認し、含まれていたら基準となる変数と、参照先の相対位置を保存する。
(3)参照先が、他の全てのグローバル変数のアドレスに一致しないかどうかを確認し、一致した場合どの変数に一致するかの記述を保存する。
(4)参照先が特定できなかったものは、それがNULLでないか、並びにスタック領域を参照していないかを確認し、どちらにも該当しないものは、変数の型に従った領域をバイナリで保存する。これは一般に存在しない。
(5)参照先がNULL、またはスタック領域と考えられるものは、全てNULLとして保存する。
これで、基本的なグローバル変数の値と復元のための情報を保存することができる。
【0026】
次に、保存した計算状態としてのグローバル変数を用いて、任意の復元ポイントで計算状態を復元する復元方法について説明する。図8に、復元してプログラムを再開するためのプログラム記述を図6に示すソースプログラムに追加した例を示す。図8に示すソースプログラムでは、ユーザにより復元ポイントが指定された場合、復元を実施する(611)。復元処理においては、指定された復元ポイントに対応する保存ファイルを開き(711)、読出復元処理(712,713)を行った後、読み出した保存ファイルを閉じ(714)、本体処理における繰返数の初期値を、713で読み出した値インクリメントした値に置き換える(715)。
【0027】
また、繰り返し処理の前に指定した保存ファイルの内容を復元して、繰り返し処理を途中から開始する手順について、図9に示すフローチャートを用いて説明する。なお、繰返数をk、繰返終了回数をK、復元を行う繰返数(復元ポイント)をnとする。復元ポイントは、ユーザが入力手段13からパラメータを入力することにより指定する。まず、図7の場合と同様に、初期化処理と繰返数kの初期化を行い(ステップST201)、パラメータ入力(ステップST202)を行う。入力されたパラメータに復元を行う繰返数の指定があるかどうかを確認し(ステップST203)、なければそのまま初期化を反映して最初から計算を開始する。指定があれば、保存されたファイルのうち、復元を行う繰返数以下で、最も近い繰返し数に対応する保存ファイルを開き(ステップST204)、グローバル変数の内容を復元して(ステップST205)、main_calcに与える引数の初期値を取得し、最後に繰り返し処理の繰返数kの初期値を、読み出した値nに1を加えた値に置き換える(ステップST206)。その後繰り返し処理(ステップST207〜ST210)が行われるが、for文の繰返数の初期値が保存ファイルを生成したタイミングの次の値を示しているので、保存した直後からシミュレーションが再開されることになる。これにより、保存したタイミングまでの計算時間は不要となる。
【0028】
図8において、[グローバル変数の読出復元処理](712)で規定するグローバル変数の復元処理(ステップST205)について以下に示す。基本的に保存処理に対応した手順となる。
0.メモリ確保領域の開放
初期化処理の中でメモリ領域の確保を行い、グローバル変数で参照しているものは、確保したメモリを解放する。
1.全てのグローバル変数(通常の変数、配列変数、ポインタ変数で共通)
変数の型、配列の場合はさらに要素数に従って、そのサイズの領域にバイナリ形式で保存された値をロードする。
2.全てのポインタ変数(ポインタ配列の要素、構造体内部のポインタを含む)
(d)前記保存処理の2.(a)および(b)の変数について、該当するサイズのメモリ領域を確保し、そこへ保存ファイルにバイナリ形式で保存された内容をそれぞれロードする。
(e)前記保存処理の2.(a)および(b)に該当しない変数は、保存した際の条件にそれぞれ従って、以下の処理によって復元する。なお、以下の括弧付き番号は、前記保存処理の2.(c)に記載した条件に合致したものにそれぞれ対応する。
(1)保存ファイルに示された参照先である変数の、現在の値(変数の実体のアドレス、あるいは前記(d)のポインタ変数の値)をそれぞれ代入する。
(2)保存ファイルに示された参照先である領域の現在の値と、保存ファイルに示された相対位置から値(アドレス)を算出してそれぞれ代入する。
(3)保存ファイルに示された参照先の変数の現在のアドレスをそれぞれ代入する。
(4)変数の型に従ったサイズのメモリ確保を行ってそのメモリ領域を当該変数で参照し、さらにそのメモリ領域に保存ファイルの内容をそれぞれロードする。
(5)すべてNULL、つまり0を代入する。
【0029】
なお、ソフトウエアプログラムの途中状態の保存・復元は、ここに記述した内容でいかなるプログラムにおいても対応できるわけではないが、プログラム内部での記述が変数の型に忠実であれば、上記対応をベースに保存・復元処理を記述することで対応可能である。いずれにしても、グローバル変数のみの保存・復元は、通常のソフトウエア技術で十分に可能である。また、プログラムの再開も本構成においては繰り返し数の指定だけで可能であり、簡単かつ確実にソフトウエアプログラムの途中状態を復元でき、再開を行うことができる。これでまず、一度計算を実施した後、結果を見て、再度計算を実施して詳細情報を抽出したり、デバッグをしたりするときに、最初から計算をやり直すのではなく、確認したいタイミングより前でかつ最も近いタイミングで保存された途中経過保存ファイル(以下で、スナップショットとする)を使用してそこから計算を再開することで、最初から計算した場合にそのタイミングに達するまでに必要な計算時間を節約することができる。
【0030】
また、市販、あるいはオープンソースのプログラムデバッガを用いてデバッグを行う場合について示す。プログラムデバッガを用いる場合の計算処理装置では、以下の段階を踏むことになる。
1.途中経過状況保存を実施するように設定して全体の計算を行い、結果を確認して、期待されない動作が行われていることを認識する。
2.概略のログ表示を確認し、大体の異常発生時刻を特定する。
3.途中経過状況保存をより高頻度に、またログをより詳細にして、発生直前の途中経過保存ファイルを利用して計算を再開する。
4.異常発生時刻を経過してから計算を止め、詳細ログから異常発生を再度確認する。
5.デバッガ上でプログラムを起動し、異常発生時刻に最も近い途中経過保存ファイルを利用して、そこからプログラムを再開して、プログラム記述レベルのデバッグを進める。
これにより、異常発生まで何度でも短い時間で達することができ、デバッグ効率をさらに向上させることができる。
【0031】
再開を矛盾なく行うためには、[本体処理](301)に変更を加えてコンパイルすることはできないが、追加した最上位のソースプログラムは変更することができる。このため、最上位のソースプログラムの修正を行った場合でも、途中から計算を再開することができ、デバッグまたは再処理の作業効率を向上させることができる。また、[本体処理](301)はこの上位プログラムで参照可能なグローバル変数を使用しているので、復元直後、あるいは異常発生の前後など、繰り返し処理の合間にグローバル変数の値を変更することは任意である。
【0032】
この特徴を利用して、最初に長時間の計算を行う時には取得しきれなかった変数、あるいは変数の詳細情報を取得して、デバッグ、あるいは評価を行うためのプログラム記述例を図10に示す。図10では、図8における途中経過の復元処理(611、711〜715の処理)をまとめて[途中経過復元処理](611、711〜71)としている。一般にシミュレーションなどで対象の評価を行うときは、パラメータや設定をいくつかのパタンで用意し、昼夜を問わず連続的に計算を行わせて、後でそれら全ての結果を確認するという作業の流れが一般的である。そのため通常保存するログやデータは、必要最低限に抑える。よって、異常発生は認識できても、原因を特定するまでの情報はその時点では取得できていないのが一般的である。
【0033】
そこで、図10では、異常発生が"繰返数"で154223のタイミングだったとして、その前後の繰返数(154211〜154230)において、より詳細な情報を取得するために、[変数の内容を表示](721)、[プログラムトレースの表示](722)、[変数の内容をファイルに保存](723)を追加している。ここで、図10の[変数の内容を表示](721)および[変数の内容をファイルに保存](723)における"変数"とはグローバル変数である。特にこれは、グローバル変数の内容を参照して、表示または保存処理をしているだけであるので、変数値の変更等をしているものではなく、main_calc関数の処理に影響はない。また、途中経過の復元・再開も最初の計算で取得したスナップショットを用いて問題なく復元可能である。
【0034】
また、[プログラムトレースの表示](722)のように処理の詳細を表示するプログラムトレース機能などを用意しておくと、バグの種類によってはこれだけで原因が特定でき、デバッガを用いなくとも原因の特定を行うことができる場合がある。これは、異常を認識してもいない最初の計算実施の段階で適用した場合、大量の表示を行い、表示を保存するだけで相当のCPUタイムを奪ってしまうため、詳細な情報を取得する段階で適用する。なお再計算する際には、スナップショットの保存頻度を上げることにより、より作業効率を上げることができる。ただし、目的のタイミングに達するまで1分程度になれば十分と考えられる。
【0035】
更にグローバル変数を変化させながらデバッグ、あるいは評価を進めるためのプログラム記述例を図11に示す。ここでは、異常発生のタイミングである154223におけるプログラム本体(main_calc)の計算の前に、2つのグローバル変数の値を変更してする処理[グローバル変数Aの値をx1に変更](731)、[グローバル変数Bの値をx2に変更](732)を追加している。また、続く154224のタイミングにおいても、グローバル変数の値を変更する処理[グローバル変数Aの値をx3に変更](733)、[グローバル変数Bの値をx4に変更](734)を追加している。このように値を変化させ、明示的に"元のソフトウエアプログラム([本体処理])"の動作に影響を与え、結果を確認することも可能である。この程度の変数の変更であればデバッガを利用しても簡単に行えるが、より多くの変数の変更を、更には一定のパタン、あるいはファイルに記述した内容で行う場合には、プログラム記述で実施できることは極めて有効である。そうした場合のプログラム記述例を図12に示す。なお、各処理とmain_calcの位置関係は目的に応じて決めればよく、当然この限りではない。図12では、繰り返し処理の前で"繰返数"毎にグローバル変数に適用すべき値をリストアップした変数値定義ファイルをオープンし(741)、繰り返し処理の中で、"繰返数"が一定の条件になったらグローバル変数の変更を開始する(641)。グローバル変数の変更のための記述は、変数名と値(バイナリ)のセットを各繰返数毎に読み出して、順次適用する(742、743)。"繰返数"が一致しなければ適用しないなどの手順を入れるとより使いやすくなる。そして繰り返し処理を抜けてから、ファイルをクローズする(744)。
【0036】
実施の形態1に係る計算処理装置では、以上のような構成をしているため、専用装置を用いる必要がなく、こうした効率的なデバッグ等の実施手段を各種の広範なソフトウエアプログラムに適用することができる。また、各処理を関数として独立して定義することにより、一部の関数を修正して再計算する場合でも、別の関数やその上位のソースプログラムに関しては修正を行う必要がなく、ソースファイルの管理やコンパイルなどの作業が容易となり、作業効率を向上させることができる。また、保存を繰返し処理の度ではなく、一定の間隔ごとに行うことにより、計算状態の保存に必要な容量を減らすことができ、保存した計算状態から再実行することにより、効率的に計算状態の復元を行うことができる。また、グローバル変数をその特性に応じて保存方法を変えることにより、ポインタ変数等を用いた場合においても矛盾なく計算状態の復元を行うことができる。
【0037】
実施の形態2.
実施の形態1では、古典的なC言語など、オブジェクト指向プログラミングではない言語での適用について示してきたが、実施の形態2ではオブジェクト指向言語、特に近年広く適用されているJava(登録商標)を用いた場合について示す。実施の形態2に係る計算処理装置の構成は図1と同様であり、基本的な状態保存手順および状態復元手順を表すフローチャートは図7、図9と同様である。以下では、図1に示す計算処理装置に実行させるソフトウエアプログラムの記述方法について述べる。
【0038】
オブジェクト指向言語においても、デバッグや再評価の対象となるソフトウエアプログラムの基本構成は実施の形態1の場合と同様である。また、新たに記述する最上位のソースプログラムについては図3の記述と基本は同じであるが、図13に示すように、オブジェクト(クラス)を規定する記述で囲まれる(001、002)。また、関数をメソッドと呼ぶのが一般的であり、グローバル変数に相当するものは各クラスの中に定義され(551)、フィールドなどと呼ばれる。
【0039】
次に、元のソフトウエアプログラムの各処理をオブジェクトとして関数化したソースプログラムの記述例を図14に示す。関数化については図4と同じであるが、クラスを規定する記述(001、002)、およびグローバル変数をフィールドとしている(551、552)点が異なる。また初期化を行うinitializeは、このままメソッドとしても良いが、ここでは、オブジェクトを構築するコンストラクタとして記述している(251)。コンストラクタはオブジェクト(クラス)名称と同じ名前を指定する。またコンストラクタに与える引数についても図4と同様で、コマンド引数をそのまま与えることになる。ここでも他のメソッド(main_calcまたはfinishing)でコマンド引数を参照する必要があれば、新たなフィールドを宣言しておいてそこにコマンド引数を保存しておくなどの対応を行う。
【0040】
そして、最上位のソースプログラムとして新たに記述するソースプログラムを図15に示す。これもクラスを示すための記述(011、012)が追加されている他は、プログラムの構成としては図5と特に変わらない。ただし、"元のソフトウエアプログラム"は記述上も本質的にオブジェクトとなり、オブジェクトとして実体(インスタンス)が宣言され、そこでまず初期化が行われるが、初期化にあたり、コマンド引数をそのまま引数として与えている(801)。そして繰り返し処理本体の計算、および後処理においても、メソッドの呼び出しとして記述がそれぞれ適用されている(802、803)。
【0041】
ここで、途中経過保存、および復元のための処理を追加した記述例を図16に示す。基本構成は図8と特に変わらないが、オブジェクト指向言語、特にJava(登録商標)においては保存・復元処理が簡単になる。なお、図8では、initializeの呼び出しを無条件で行った後、指定保存ファイルの有無を確認していたが、図16の例では、if〜elseのelseに記述して、処理が重ならないようにしている。図8のように無条件で呼び出してから上書きしても問題はない。
【0042】
記述する上で図8と異なる点を、それぞれ以下に示す。
1.オブジェクト復元処理(752)
オブジェクト(クラス)の内容をファイルから読み出し復元して、元のソフトウエアオブジェクトを示す変数aに代入する。図8の例では、グローバル変数を回復するのが主な処理であったが、オブジェクト指向言語では、記述上、フィールドの他にプログラムそのものもここで回復させることとなる。実際には、プログラムを含め、動作中変更されることのないものはコンパイル時に生成されたクラスファイルから参照され、変更可能なフィールドが保存ファイルから回復されるのが一般的である。
2.変数a参照のオブジェクトの書出(757)
オブジェクト(クラス)の内容、特に変更可能なフィールドをファイルに書き出す。上記のオブジェクトの読み書き処理は、特にJava(登録商標)言語では直列化機能として実装されていて、そのためには、保存対象のクラスのソースプログラムにおける宣言で、この直列化機能を実装するよう記述を追加するだけである。図15の011に、"implements Serializable"を追加するだけである。その内容を図17に示す。ただし、この"SimTop"以下で利用され、保存の対象となる全てのクラスにおいてこの宣言がなされている必要がある。
【0043】
ここで、図16の例では、オブジェクトの他に繰返数の保存・復元を行う必要があるが、前記オブジェクトの保存ファイルは、専用の手順によって生成されるので、オブジェクト保存専用のファイルとするのが適当である。そこで、繰返数の保存(758)・復元(753)においては、以下のような実装方法が考えられる。
3.専用のファイルを別途用意
オブジェクトを保存したファイル名から拡張子を変えるなどしたファイルを用意し、保存、復元を行う。
4.ファイル名に入れ込む
オブジェクトを保存するファイル名に、一定の桁数の領域を設けて、そこに値を記述する。[main_calc引数の保存処理](758)は括弧で囲んでいるが、この方法を適用した場合は、[新規ファイルのオープン](756)の時点で保存は完了していると言うことができる。
いずれにおいても、特に問題なく実装可能な方法である。
【0044】
なお、元のソフトウエアプログラムが、本体の計算中にずっとファイルを開いたままにしておき、継続して読み出す、あるいは書き込むなどを行う場合、オブジェクトの直列化機能を利用する場合においても一定の手順が必要になる。これらのファイルの準備に関する手順である。オブジェクト指向言語においても、ファイルの入出力を行うオブジェクトは直列化することができないため、以下の処理を行う。また、そのプログラム記述例を図18に示す。
1.保存
保存処理の前に、その時点のファイルポインタの位置を読み出し(763)、ファイルをクローズし(764)、ファイルの入出力オブジェクトを参照している変数にはnullを入力する。途中経過の保存処理においてはファイルポインタの位置も併せて保存する。またその後、処理を継続するために、再度閉じたファイルをオープンし(765)、ファイルポインタを閉じた時点の位置にそれぞれ移動させる(766)。なお、ファイルポインタ位置について、設定はできるが、読み出しはできないのが一般的であると考えられる。できない場合には、読み出し位置を示すグローバル変数、あるいはフィールドを用意し、何文字(何バイト)のデータを読み出したかなどを常に把握しておくようなプログラム記述が必要になる。
2.復元
復元処理の後に、必要なファイルをオープンし(761)、ポインタ位置を保存ファイルから取得して、対応する各ファイルのファイルポインタ位置を移動させる(762)。なお、書き込みファイルの場合は、オープンの時に追加モードでファイルを開けば良い場合が多いと考えられる。なお、必要なファイルのオープンにはそのファイルの所在(ファイル名)が必須である。そこで、グローバル変数、あるいはそのファイルを利用するオブジェクトのフィールドとして、ファイル名が保存されていなければならない。必要に応じ、プログラム記述を追加する。
【0045】
ポインタの保存に当たっては、別途ファイルを用意するか、グローバル変数として、あるいは元のソフトウエアプログラムのフィールドとして保存する。基本的に元のソフトウエアプログラムは変更しないのが望ましいが、グローバル変数、あるいはフィールドを追加し、最上位から読み書きするだけであれば本来の機能に影響を与えないで実施可能である。
【0046】
次に、一部のオブジェクトを、プログラム記述を変更してコンパイルしたものに置き換えてから計算を行う場合について示す。特にオブジェクト指向プログラミングにおいては、プログラム自体を変更させることも容易である。元のソフトウエアオブジェクトをすべて変えるのではなく、変更の対象は一部の機能(オブジェクト)である。特にデバッグなどで修正を確認する際、現象が起きる直前で、フィールドを引き継いだ上で修正したオブジェクトに置き換え、計算を継続させることで修正が確認できる場合がある。この場合、あくまでも修正前のオブジェクトを継承した別の名称のオブジェクトとして、必要な箇所を変更するようにする。そうすることで、一度元のオブジェクトで復元された後で、修正オブジェクトに置換することが可能となる。
【0047】
その変更手順のプログラム記述例を図19に示す。図19において各処理の内容は以下のとおりである。
1.置換タイミング条件の確認(641)
繰返数によって事象発生タイミングを捉える。
2.修正オブジェクトのインスタンスの宣言(771)
修正した新しいオブジェクトのインスタンスを宣言(初期化)する。
3.フィールドの引き継ぎ(772)
修正前後で共通のフィールドについて、あるいはデバッグ等において必要なフィールドについて、修正後のオブジェクトに元のオブジェクトの値を反映させる。また必要に応じ、フィールドを変更する。
4.オブジェクトの置換(773)
修正後、フィールド引き継ぎ後のオブジェクトで、元のオブジェクトを置き換える。
これで時間的にもっとも効率よく対象の事象を発生させ、修正後のオブジェクトでの動作を確認することが可能となる。
【0048】
次に、繰り返し処理が、時間離散型シミュレーションプログラムの記述において広く適用されている、イベントキューからイベント情報を読み出すことから始まるプログラムでの実施例を示す。当該プログラムの処理フローを図20に示す。図2と構成はほとんど同じであるが、イベントキューからイベント情報を読み出すことから繰り返し処理の中身が開始される(362)。一般に、このイベント情報はイベントの内容、発生箇所などのデータをまとめたオブジェクトで、当該イベントがいつ発生するかを示すシミュレーション上の時刻情報を伴い、新たにキューに保存されるイベント情報は常にこの時刻情報に基づいて昇順に並べ替えられる。したがって、キューからは時刻順に常に読み出される。シミュレーション処理の本体は、読み出されたイベント情報に従って、処理時刻を設定し、そのイベントの発生箇所(オブジェクト)、発生内容に従って処理を行う(361)。こうして、シミュレーションが進行する。
【0049】
図21に、この場合の最上位のプログラム記述例を示す。キューそのものは元のソフトウエアプログラムの一部であることが一般的であるため、オブジェクト指向言語であれば、途中経過保存処理(786)および復元処理(781)において、繰り返し処理回数(図19における"繰返数")を別途保存する必要もなく、キューの待ち行列も含めて全て保存ファイルに書き出され、また復元が可能である。よって、保存・復元処理のプログラム記述は、保存処理では図19における[main_calc引数の保存処理](758)、復元処理では図19の[main_calc引数の読出復元処理](753)が削除されている。
【0050】
また、途中経過保存のタイミングも、繰り返し処理回数ではなく、シミュレーション上の時刻で指定することが可能となる。これを実装するプログラム記述例が図21の681の繰り返し処理である。例えば、計算終了までに10回保存するとして、終了時刻がシミュレーション上の時刻で1秒だとすると、interval=0.1として、新規イベント情報(オブジェクト)の生成(781)、イベント時刻の設定(782)、イベント種別の設定(783)、そしてキューへのイベント情報の登録(784)の各処理を10回行うことで、各保存時刻に保存イベントが読み出されるための準備が完了する。厳密には、10回目は計算終了時刻となり、途中経過保存の必要性は通常ない。
【0051】
繰り返し処理の記述は、"while(true)"で始まる無限ループとなる(291)。このループの中で、キューからイベント情報を読み出す度にイベント時刻を確認し、終了時刻よりも後の時刻を検出したら、そこでwhileを抜け、計算終了となる(682)。そして経過保存処理は、イベント種別が経過保存実施に一致すると行われ(683)、これでシミュレーション上の時間で0.1秒毎に途中経過が保存される。また計算の本体はこれまで通り呼び出すが、引数は、図19までの例では必須であった"繰返数"はなく、代わりにイベント情報(オブジェクト)が必須の引数となる(381)。
【0052】
実施の形態2に係る計算処理装置では、以上のように記述したソフトウエアプログラムを実行することにより、オブジェクト指向プログラミングを用いた場合でも実施の形態1と同様の効果が得られる。なお、繰り返し処理がないものでも、一連の処理を複数のメソッドに分けることによって同様の効果が得られる。また、ここではオブジェクト指向プログラムとしてJava(登録商標)を用いた場合について示したが、これに限られるものではなく、その他のオブジェクト指向言語を用いた場合でも同様の効果が得られる。
【符号の説明】
【0053】
11 プログラム実行手段、12 メモリ、13 入力手段、14 表示装置

【特許請求の範囲】
【請求項1】
第1の演算プログラムおよび第2の演算プログラムを有するソフトウエアプログラムを実行する計算処理方法であって、
前記第1の演算プログラムを実行する演算実行ステップ、
前記第1の演算プログラムとは独立してその内容が規定された前記第2の演算プログラムを、複数回繰返し実行する繰返実行ステップ、
前記繰返実行ステップにおいて、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存ステップ、
を備える第1の演算ステップと、
前記ソフトウエアプログラムの修正要否に応じて、前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定する復元ポイント指定ステップ、
前記状態保存ステップで保存された計算状態のうち、前記指定された復元ポイントに対応する繰返し回数における前記保存された計算状態を選択して読み出す選択読出ステップ、
前記選択された計算状態に基づいて、前記第2の演算プログラムを実行する復元ステップ、
を備える第2の演算ステップと、
を備えることを特徴とする計算処理方法。
【請求項2】
前記第1の演算プログラムと前記第2の演算プログラムは、前記ソフトウエアプログラムにおいて、それぞれ異なる関数として定義されたことを特徴とする請求項1記載の計算処理方法。
【請求項3】
前記状態保存ステップでは、前記ソフトウエアプログラムにおいて定義されるグローバル変数を、前記グローバル変数の特性に応じた保存方法により保存し、
前記選択読出ステップでは前記保存されたグローバル変数を読み出すこと、
を特徴とする請求項1または2のいずれかに記載の計算処理方法。
【請求項4】
前記状態保存ステップで保存されたグローバル変数を修正する修正ステップを備え、
前記選択読出ステップは、前記修正ステップにおいて修正されたグローバル変数を読み出すこと、
を特徴とする請求項3記載の計算処理方法。
【請求項5】
前記選択読出ステップにおいて読み出されたグローバル変数を修正する読出修正ステップを備え、
前記復元ステップは前記修正されたグローバル変数に基づいて、前記第2の演算プログラムを実行すること、
を特徴とする請求項3記載の計算処理方法。
【請求項6】
計算機に、
第1の演算プログラムを実行する演算実行ステップ、
前記第1の演算プログラムとは独立してその処理内容が規定された第2の演算プログラムを、複数回繰返し実行する繰返実行ステップ、
前記繰返実行ステップにおいて、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存ステップ、
を備える第1の演算手順と、
前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定させる復元ポイント指定ステップ、
前記状態保存ステップで保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出ステップ、
前記選択された計算状態に基づいて、前記第2の演算プログラムを実行する復元ステップ、
を備える第2の演算手順と、
を実行させることを特徴とするソフトウエアプログラム。
【請求項7】
第1の演算プログラムおよび第2の演算プログラムを有するソフトウエアプログラムを実行する計算装置であって、
前記第1の演算プログラムを実行する演算実行手段と、
前記第1の演算プログラムとは独立してその処理内容が規定された前記第2の演算プログラムを、複数回繰返し実行する繰返実行手段と、
前記繰返実行手段において、予め定められた回数繰返し実行した場合に、前記予め定められた回数実行終了時の計算状態を保存する状態保存手段と、
前記ソフトウエアプログラムの計算状態を復元する復元ポイントを指定する復元ポイント指定手段と、
前記状態保存手段で保存された計算状態のうち、前記指定された復元ポイントに近い繰返し回数における前記保存された計算状態を選択して読み出す選択読出手段と、
前記選択読出手段で選択された計算状態に基づいて、前記第2の演算プログラムを実行する復元手段と、
を備えることを特徴とする計算処理装置。

【図1】
image rotate

【図2】
image rotate

【図3】
image rotate

【図4】
image rotate

【図5】
image rotate

【図6】
image rotate

【図7】
image rotate

【図8】
image rotate

【図9】
image rotate

【図10】
image rotate

【図11】
image rotate

【図12】
image rotate

【図13】
image rotate

【図14】
image rotate

【図15】
image rotate

【図16】
image rotate

【図17】
image rotate

【図18】
image rotate

【図19】
image rotate

【図20】
image rotate

【図21】
image rotate


【公開番号】特開2012−38019(P2012−38019A)
【公開日】平成24年2月23日(2012.2.23)
【国際特許分類】
【出願番号】特願2010−176233(P2010−176233)
【出願日】平成22年8月5日(2010.8.5)
【出願人】(000006013)三菱電機株式会社 (33,312)
【Fターム(参考)】