• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:処理負荷特定で考えられる要因について)

処理負荷特定で考えられる要因について

このQ&Aのポイント
  • 処理負荷の高い現象が発生している関数Aについて、その要因を考える必要があります。関数AはVC6(SP6)上のWin7で動作しており、iniファイルへの書き込み処理を行っています。関数Bから呼び出される構造になっており、関数Aの処理時間が不定期に30秒以上かかる現象が発生しています。原因を特定するために、関数Aの内容や環境の要素、セキュリティソフトの影響などを考える必要があります。
  • 以前にも似た現象が発生した際、ウイルスバスターの影響が指摘されました。関連する要素として、ファイルオープン/クローズの回数が50回前後繰り返されており、この処理が大幅な負荷を引き起こす可能性があります。現在の状況では、ウイルススキャンのソフトウェアはインストールされていないため、その影響は考えにくいですが、確認する価値があります。
  • 関数Aの処理時間が通常よりも長くなる原因は、いくつか考えられます。まず、関数Aで使用しているAPIや標準関数の仕様やパフォーマンスに問題がある可能性があります。また、iniファイルの操作が効率的でない場合、処理負荷が高くなる可能性もあります。さらに、使用している環境や他のプロセスとの干渉、DI/Oボードの影響なども考慮する必要があります。これらの要素を調査し、現象の原因を特定することが重要です。

質問者が選んだベストアンサー

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.2

ローカルファイルにあるINIファイルを変更しているんですよね。 #ネットワーク越しに共有しているファイルとかじゃないかということ それから、50回のオープンクローズを1回にしてみると、状況が変わるかとか、 関数Aをコールしない場合は、そういう事象は発生しないということも確認済? 構造を改善するのが一番よさそうだけど、例えば、その頻繁にアクセスするINIファイルは、 RAM上に置き(RAMディスク作成ツールでRAMドライブを作る)、RAM上での書き換えが終わったら、 ディスクに書くようにするとか。

koi1234
質問者

お礼

数点の可能性含め考えるとべき内容もある程度見当ついてきました 様子見のじょゆ教で時間がどれだけかかるか分からないので 一旦閉じさせていただきます

koi1234
質問者

補足

回答ありがとうございます >ローカルファイルにあるINIファイルを変更しているんですよね。 そうです >50回のオープンクローズを1回にしてみると、状況が変わるかとか、 此方に関しては質問文に書いたように躊躇している状態です >関数Aをコールしない場合は、そういう事象は発生しないということも確認済? 頻度の問題確実に確認できているというわけではありません 今現状ではっきりしているのはその処理内で異様に時間がかかることがある ということだけです >構造を改善するのが一番よさそうだけど、例えば、その頻繁にアクセスするINIファイルは、 >RAM上に置き(RAMディスク作成ツールでRAMドライブを作る)、RAM上での書き換えが終わったら、 完全な構造変更というのが諸事象で難しい点もあるのですが 他で同様なことをやって逃げていた前歴がありました    すっかり忘れ去ってました    同様対処で発生事象が改善されたことも確認しています システム上今からRAM DISKなどを構築するのは不安があるので 一旦作業用フォルダにコピー そちらのファイルに対して現状の処理を行い終了後再度コピーする といった方法がありますね #1さんの書かれたように本当に都度オープンクロースしてるのかという話と 遅延書き込みとか影響ないのか 等ちょっとわからない点もありますが やってみる価値はありそうな気がします

その他の回答 (4)

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.5

あのー、「調査のためにコードを修正すること」まで躊躇ってませんか? 例えば、ファイルが他のプロセスによって専有されているかどうか、 その他のソースコードを読んで、ない「はず」というよりも、 自分のプロセスで当該ファイルをCreateFileの排他ロックで開く・閉じるを繰り返すようなコードを 書いて(関数B内でファイルのロックを握ろうとして)失敗することがあれば、 他のプロセスが握っているんだろうと思います。 #GetLastErrorで調べられると思います。 他にも、処理時間が30秒もかかっているときには、WritePrivateProfileStringの 戻り値は失敗を返してないか?とか、色々と調べるべきことがあると思います。 私なら再現頻度を調べて、1ヶ月に1回とかなら、時間的な制約でソースコードから 調査しますし、1日1回とかであれば、ログを各所に埋め込んだり、上記のような 調査用のコードを走らせてみます。 最終的にソースコードを書きなおすかどうかはともかくとして、 原因がソフト的な問題か、ハード的な問題か?を切り分ける必要はあると思います。 原因をしっかり突き止めないと、後々どこかでしわ寄せが来ます。

koi1234
質問者

お礼

数点の可能性含め考えるとべき内容もある程度見当ついてきました 様子見のじょゆ教で時間がどれだけかかるか分からないので 一旦閉じさせていただきます

koi1234
質問者

補足

>あのー、「調査のためにコードを修正すること」まで躊躇ってませんか? そのつもりはないんですがそう見えたらすいません >私なら再現頻度を調べて、1ヶ月に1回とかなら、時間的な制約でソースコードから >調査しますし、1日1回とかであれば、ログを各所に埋め込んだり、上記のような >調査用のコードを走らせてみます。 頻度とか含めて以前からログを各所に埋め込んだりしてという状態で 今のところまで来ているといった状態です

回答No.4

No.1 です。 外付けのHDDが、中途半端に大きなバッファを持っていて、それがあふれたときに時間がかかる……というのも、可能性としては考えられますが、それだと、30秒は長すぎますね。 > XP以前の ini ファイル推奨時代は 書き込み終了させるための > フラッシュ関数があったような記憶もあるのですが…… http://msdn.microsoft.com/ja-jp/library/cc429952.aspx によると、Windows 95 では、 WritePrivateProfileString(0, 0, 0, filename); でバッファをフラッシュするそうです。

koi1234
質問者

お礼

数点の可能性含め考えるとべき内容もある程度見当ついてきました 様子見のじょゆ教で時間がどれだけかかるか分からないので 一旦閉じさせていただきます

koi1234
質問者

補足

>WritePrivateProfileString(0, 0, 0, filename); >でバッファをフラッシュするそうです 引数でしたか  そりゃ関数探しても見つからんわ 何かほかの言語と勘違いしてたのかもしれません

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

質問内容からわからないことをいくつかお聞きします。 ・開発環境はWindows7上との事ですが、  実行環境も同等の環境でしょうか?  >現在 Win7上のVC6(SP6)にて   とありますが、まず第1にVc6は  既にサポートが終了されており、  Vista以降のOSでは仮に動作したとしても、  その保証がないことをご留意ください。 ・既に質問者さんも経験がおありのようですが、  別の関係ないプロセスがファイルをつかんでいる可能性は  ありませんでしょうか?  ウィルス対策ソフト以外に、バックアップ系の  ソフトウェアなどが考えられます。 ・ここからが主眼となりますが、  マルチスレッドでも動作するということですが、  排他処理などは行っていないのでしょうか?  提示された処理内容からは当該の動作を  行っていない様ですが、複数スレッドからの  書き込みは少なくとも排他する必要があると思いますが  もし排他している場合は、これで待たされているか、  もしくはもっと下回りのドライバIOレベルでの読み書き  排他に引っ掛かっている可能性があります。 ・上記と似ていますが、複数プロセスで  同じIniファイルを参照する可能性はないのでしょうか?  この場合は、スレッド間の排他と、プロセス間の  排他処理を両方行うことになり、待ち時間も  ファイルIOの状況によっては、結構な物になると思います。 また、関数A,関数Bの呼び出され方ですが、 これらはアプリケーション実行中に定期的にINIファイルを 更新する処理があるという認識であっていますか? INIファイルなどは、簡易的な使用方法として、 アプリケーション開始時に読み込み、 終了時に書き込みを行って保存しておくという 使い方が一般的だと思うので、 内部でキャッシュなどが行われる場合は 頻繁に更新された場合に、期待した動作に ならない可能性があり得るのではないかと思います。 >こうすれば簡単に置き換えが可能 一番早いのは、WindosAPIはASCII用とWide用の為に、 WritePrivateProfileStringなどの関数はDefineで置き換えられているので 引数を同じにした関数を作成し、データ部分以外の引数を捨てて fprintfなどで独自のフォーマットを使用して、読み書きを行う方法です。 関数の呼び換えを行うのは楽ですが、データのフォーマットを 考えなければなら無いためあまりお勧めできませんが。。。 #書き込みのみを一括にするという方法もあります。 適当ですが --- header #if defined( WritePrivateProfileString ) #undef WritePrivateProfileString #endif #define WritePrivateProfileString MyWritePrivateProfileString VOID CloseMyPrivateProfileString( VOID ); BOOL OpenMyPrivateProfileString( LPCTSTR ); BOOL MyWritePrivateProfileString( LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR ); --- src static FILE *fp = NULL; BOOL OpenMyPrivateProfileString( LPCTSTR lpFileName ) {  fp = fopen( FileName, "r+" );  if ( !fp ) return FALSE;  return TRUE; } VOID CloseMyPrivateProfileString( VOID ) {  fclose( fp );  fp = NULL; } BOOL MyWritePrivateProfileString(  LPCTSTR lpAppName, // セクション名  LPCTSTR lpKeyName, // キー名  LPCTSTR lpString, // 追加するべき文字列  LPCTSTR lpFileName // .ini ファイル ){  int ret;  ret = fprintf( fp, "[%s]\n", lpAppName ); //セクション  if ( ret < 0 ) return FALSE;  ret = fprintf( fp, "%s=%s\n", lpKeyName, lpString );  if ( ret < 0 ) return FALSE;  return TRUE; }

koi1234
質問者

お礼

数点の可能性含め考えるとべき内容もある程度見当ついてきました 様子見のじょゆ教で時間がどれだけかかるか分からないので 一旦閉じさせていただきます

koi1234
質問者

補足

回答ありがとうございます >開発環境はWindows7上との事ですが、 >実行環境も同等の環境でしょうか? 同じ環境です >別の関係ないプロセスがファイルをつかんでいる可能性は 無い筈なんです(ソース上で探してるがそれらしいところは見当たらない) (何処かでつかまっている可能性が高いのかなという気は確かにしています) バックアップ系のソフトなども動かしていません   特定用途限定PCとして使っているので動作に必要ではない   他のアプリケーション類は動いていない(インストールもしていない)   と考えていただいて構いません >Vista以降のOSでは仮に動作したとしても、 >その保証がないことをご留意ください。 承知しています いかんせん費用の問題とその部分でたまにそうなっているということで頭抱えています ↑があるので作成環境の問題じゃないんじゃない?  ってなことに >排他処理などは行っていないのでしょうか? これが困ったことに入り乱れてしまっているんです   (致命的になりそうなところは行っています) >同じIniファイルを参照する可能性はないのでしょうか? 該当ファイルに関して言えば他から参照の可能性はありません ただ私としても何処かで該当ファイルがロックされてしまっている ような可能性を一番に疑っています    その要因となるようなところが見当たらない為    なんでかがわからないといった状況です 別のファイルでも他のPCなどからLANアクセスされたりすると 影響あるもんなんでしょうかね? (ここら辺がよくわからない所です  単純に考えれば影響はなさそうなんですが) >これらはアプリケーション実行中に定期的にINIファイルを >更新する処理があるという認識であっていますか? 定期的といえば定期的なのですがタイマーのような定期的なものではなく データ更新されたとき一緒に更新されるといったものです 現状その時の書き込み処理をパスしても致命的にはなりそうもない事もあり (全てパスすることはできないんですが条件的にパスできるときに発生しているように見受けられた為) とりあえずそういった変更をして様子を見てもらっています >INIファイルなどは、簡易的な使用方法として、 >  省略 >使い方が一般的だと思うので、 確かに・・・・・ 私もあまり一般的な使い方だと思っていません 作ったときに手軽だからという一点だけでそのようになってしまっていて 今更状態といったところです 64K制限とかあったような気もしてるんですが動いてる 作成時(テストでは)問題なかったとかいうのもあったようで 64K は Win95時代でそうだったような気がするだけで XPではその制限なくなってるんでしょうか?   ※ 該当ファイル自体は64kもありません >一番早いのは、WindosAPIはASCII用とWide用の為に、 #2さんへの補足に書いたのですが 一旦該当ファイルを作業用ファイルとして別名でコピー コピー先に対して書き込み実行  ファイルを書き戻す といった方法が一番手っ取り早くできそうかな   と思い当りました 書いていただいたコードも参考にさせていただきたいと思います 可能性含めまだしばらく情報を求めたい為 質問自体はまだしばらく閉じないつもりです

回答No.1

もしかしたらですが、Windows 7 で動いているパソコンが、SSDを使っているということはないですか。 SSDは短時間にファイル処理をすると時々固まりますが。(最近は大丈夫なのかな?) あと、ini ファイルをAPI経由で書き換えるのは、普通ですし、WritePrivateProfileString() が呼び出しの度に、実際にファイルをオープンクローズしているかは、微妙ですが。

koi1234
質問者

お礼

数点の可能性含め考えるとべき内容もある程度見当ついてきました 様子見のじょゆ教で時間がどれだけかかるか分からないので 一旦t辞させていただきます

koi1234
質問者

補足

書き込みありがとうございます この前I/F変わってから初めて質問したため 補足のつけ方がわからずに焦りました >Windows 7 で動いているパソコンが、SSDを使っている SSIDの使用はしていません ただし? HDDの増設(SATA 500G)は行っており そちらの増設DISKでプログラムを実行しています 増設HDD(or 標準HDD)でもそういった事象の可能性というのはありえるのでしょうか? (可能性の話だけだったらあるとしか言えない質問かもしれませんね) もう少し細かいPC環境的は Win7(正確には英語OS)+ VC6(SP6 これも英語版)  マザー P7P55D-E CPU i5 メモリ 4G  (自前組上)  HDD 300G(C) + 500G(D) + 光学ドライブ(E) >実際にファイルをオープンクローズしているかは、微妙 確かにそうですね 私もそこまで細かく確認しているわけではないですし OS内部動作が絡んできてしまうので具体的な調べ方も思いつきません XP以前の ini ファイル推奨時代は 書き込み終了させるための フラッシュ関数があったような記憶もあるのですがそれらしき 関数がなんだったか忘れてしまいました(& 探し方が悪いのか見当たらない)  ->そういった関数があるということは常に行っているのかも微妙    ってことなのかもしれません

関連するQ&A