1

主に行列の乗算、加算などを実行する C++ のプログラムがあります。

問題は、計算が約 300 万回実行されると EXC_BAD_ACCESS が発生することです。

問題が数百万回、数時間実行された場合に発生する可能性のある問題はありますか?

プログラムの詳細:

このプログラムは、さまざまな範囲の値を単純に計算するだけなので、同時に 6 つのスレッドで実行されます。スレッド間のリソース共有はありません。

次の理由から、プログラムに明らかな問題はないようです。

  1. メモリ リークはなく、Instruments を使用してこれを確認しました。プログラムのメモリ サイズは安定しています。
  2. プログラムは各スレッドで少なくとも 200 万回問題なく実行できますが、EXC_BAD_ACCESS 例外が何らかのスレッドで発生することはほぼ保証されています。(例外は、プログラムの 2 回の試行 (2/2) で発生します)

行列の乗算について:

行列のサイズが約 2*2 に 2*1000 を掛けたものになる場合があります。

行列の要素は、カスタムの複素数クラスです。

要素の値は rand() によってランダムに生成され、float に変換されます。

構造は次のようになります。

class Complex
{
private:
    float _real, _imag;
public:
   // getters, setters and overloaded operators
};

class Matrix
{
private:
    Complex **_values;
    int _row,_col;
public:
     getters, setters and overloaded operators
};

どうもありがとうございました!

クラッシュの考えられる理由は大歓迎です!

4

3 に答える 3

2

EXC_BAD_ACCESS は、プロセスの現在のメモリ空間を指していないポインターを逆参照したことを意味します。これはコードのバグです。失敗するまでデバッガーで実行し、失敗したステートメントの変数値を調べます。シンプルな場合もあれば、非常に微妙な場合もあります。

于 2013-09-22T00:46:28.333 に答える
1

あなたの投稿には、決定的な答えを出すには情報が少なすぎます。ただし、現在入手できる情報で変更できない可能性があるため、ケースをより慎重にデバッグする必要があります。これが私がすることです。

デバッグするには、再現性が必要です。でも…乱数を使っているとおっしゃいますね。ただし、あなたのプログラムが行うことは、科学的な計算のようです。ほとんどの場合、実際には「真の」ランダム性は必要ありませんが、「反復可能な」ランダム性は必要ありません。つまり、統計テストに合格するランダム性ですが、乱数ジェネレーターをリセットするのに十分なデータがあるため、以前の実行。そのためには、計算の新しいブロックを開始するたびに、現在の RNG 状態 (シードなど) を書き留めることができます。

ここで、計算 (RNG を含む) を数分ごとに再開するために必要なすべての状態を格納するコードを記述し、プログラムを実行します。このようにして、コードがクラッシュした場合、まったく同じ状態で計算を再開し、数百万回の反復を待たずにクラッシュしたポイントに到達できます。ここでは、RNG を除いて、コードは他の種類の外部状態 (ネットワーク アクティビティ、IO、スレッドのスケジューリング時に特定の選択を行うプロセス スケジューラなど) に依存しないという強い仮定を置いています。

この種のデータを使用すると、問題がマシンの障害 (過熱、不良メモリなど) によるものかどうかを簡単にテストできます。クラッシュする前の最後の状態で計算を再開するだけです — できればマシンを冷やした後、おそらく再起動してください... 別のクラッシュが発生した場合 (コードを再起動しようとするたびに発生します)、それが原因であることは間違いありません。コードのバグ。

そうでない場合でも、マシンのせいだとは言えません。制御できない要因に依存する未定義の動作が原因で、(純粋な偶然/コードの間違いによって) コードがクラッシュする可能性があります。例としては、めったに使用されないコード パスで初期化されていないポインターを使用することが含まれます。アクセスが悪い場合があり、ポインターが割り当てられたメモリを指しているのがまったくの偶然である場合は気付かれないことがあります。valgrindを試してみてください。これはおそらくメモリの問題をチェックするための最良のツールです... ただし、実行が非常に遅くなるため、待機するのではなく、疑わしいことがわかっている状態 (クラッシュする前の最後の状態) から計算を再実行することをお勧めします。何百万回も繰り返します。5 倍から 100 倍の速度低下が見られました。

それまでの間、別のマシンでコードを実行してみてください。同様の回数の反復後にクラッシュが発生する場合 (元のマシンでクラッシュするのにかかった回数の少なくとも 3 倍の反復を確実に待つ必要があります)、それはコードのバグである可能性が非常に高くなります。

ハッピーハッキング!

于 2013-09-22T01:19:43.113 に答える
0

数百万回の反復後に失敗する有限精度の計算? それは累積された丸め誤差である可能性があります。問題は、それらは通常、ゼロによる除算またはその他の数学的エラーとして現れることです。EXC_BAD_ACCESSではありません。ただし、これが発生する可能性があるケースが 1 つあります。それは、数学的な結果を配列インデックスとして使用する場合です。

于 2013-09-22T22:22:02.687 に答える