2016-06-24 4 views
0

私は最近、私の "main.cpp"コードをWin32コンソールプロジェクトで書いています。それはソリューションを完全に構築し、外部リリースのバージョンは30秒以内に実行され、完了します。これは計算の回数が速いためです。2D ++のMFCスローランタイム

いくつかの2Dベクトルを作成して計算する必要がある場合、単なる浮動小数点入力のための標準ダイアログボックスを1つだけ作成したMFCビルドUIを使用すると、うまく実行されたプログラムがハングアップします。

std::mt19937 generator3(time(0)); 
static uniform_01<std::mt19937> dist3(generator3); 

std::vector<int> e_scatter; 
for (int i = 0; i <= n; i++) 
{ 
    if (dist3() >= perc_e) 
    { 
     e_scatter.push_back(1); 
     // std::cout << e_scatter[i] << '\n'; 
     // system("pause"); 
    } 
    else 
    { 
     e_scatter.push_back(0); 
     // std::cout << e_scatter[i] << '\n'; 
     // system("pause"); 
    } 

} 
string fileName_escatter = "escatter.dat"; 
FILE* dout4 = fopen(fileName_escatter.c_str(), "w"); 
for (int i = 0; i <= n; i++) 
{ 
    fprintf(dout4, "%d", e_scatter[i]); 
    fprintf(dout4, "\n"); 
    // fprintf(dout2, "%f", e_scatter[i]); 
    // fprintf(dout2, "\n"); 
}; 
fclose(dout4); 

std::vector<vector<float>> electron; 
// std::vector<float> angle; 
**randutils::mt19937_rng rng2; 
std::vector<float> rand_scatter; 
for (int i = 0; i <= n; i++) 
{ 
    std::vector<float> w; 
    electron.push_back(w); 
    rand_scatter.push_back(rng2.uniform(0.0, 1.0)); 
    for (int j = 0; j <= 2000; j++) 
    { 
     if (e_scatter[i] == 0) 
     { 
      electron[i].push_back(linspace[j] * (cos((rand_scatter[i] * 90) * (PI/180)))); 
      //electron[i][j] == abs(electron[i][j]); 
     } 
     else 
     { 
      electron[i].push_back(linspace[j]); 
     }; 
    }; 
};** 

具体的には、特定のforループを過ぎることはなく、私は強制的に閉じます。私はそれがちょうどより遅いものを計算していたかどうかを見るためにそれを20分間走らせたが、まだそれから0の出力を得た。私は、コンソールをポップアップしていないので、私はMFCからこのGUIを持っているときにコードのデバッグ部分で素晴らしいことではありません。

guiと大きな2DベクトルにMFCを使用しようとすると、何か不足していますか?

最初のループは、出力ファイル 'escatter.dat'を計算して終了した後に吐き出しますが、2番目のループのセットは決して終わらず、メモリ使用量は増え続けます。

linspace [i]はこのコードの前に計算され、double forループ内にstd :: vector>電子ベクトルを設定するために使用する2001年の数字のベクトルです。

Iveにはこのhttp://pastebin.com/i8A7t38Kが含まれています。これは、実際にこの記事を読むのに時間がかからないようにするために使用していたコードのMFC部分へのリンクです。

ありがとうございます。

+0

のように推測では、MFCプロジェクトはチェックのトンを追加し、デバッグモードでコンパイルされていることですベクタアクセスに割り当てます。それは簡単に数秒に秒を回すことができます。 –

+0

私はデバッグモードでそれを完全に忘れていました。あなたは100%正しいです。ありがとうございました! – Kazkek

答えて

0

私は、デバッグチェックが大きな問題であることに同意します。 プログラムが30秒実行されている場合、nは大きくなければなりません。

vector :: reserveを使用してメモリを事前に割り当てることによって、メモリ割り当てを減らすためにコードを最適化することを検討してください。

std::vector<vector<float>> electron; 
// std::vector<float> angle; 
**randutils::mt19937_rng rng2; 
std::vector<float> rand_scatter; 
electron.reserve(n+1); // worth for big n 
rand_scatter.reserve(n+1); // worth for big n 
for (int i = 0; i <= n; i++) 
{ 
    std::vector<float> w; 
    electron.push_back(w); 
    rand_scatter.push_back(rng2.uniform(0.0, 1.0)); 
    electron[i].reserve(2000+1); // really worth for big n 
    for (int j = 0; j <= 2000; j++) 
    { 
     if (e_scatter[i] == 0) 
     { 
      electron[i].push_back(linspace[j] * (cos((rand_scatter[i] * 90) * (PI/180)))); 
      //electron[i][j] == abs(electron[i][j]); 
     } 
     else 
     { 
      electron[i].push_back(linspace[j]); 
     }; 
    }; 
};** 

か(あなたはすべてのサイズを知っているので)一backを使用しないことにより、書き換え

std::vector<vector<float>> electron(n+1); 
// std::vector<float> angle; 
**randutils::mt19937_rng rng2; 
std::vector<float> rand_scatter(n+1); 
for (int i = 0; i <= n; i++) 
{ 
    std::vector<float>& w=electron[i]; 
    w.reserve(2000+1); 
    float r=rng2.uniform(0.0, 1.0); 
    rand_scatter[i]=r; 
    for (int j = 0; j <= 2000; j++) 
    { 
     float f; 
     if (e_scatter[i] == 0) 
     { 
      f=linspace[j] * (cos((r * 90) * (PI/180))); 
      // f=abs(f); 
     } 
     else 
     { 
      f=linspace[j]; 
     }; 
     w[j]=f; 
    }; 
};** 

そのランタイムは、せいぜい数秒に低下することがあります後。

ところで

別の最適化

string fileName_escatter = "escatter.dat"; 
FILE* dout4 = fopen(fileName_escatter.c_str(), "w"); 
for (int i = 0; i <= n; i++) 
{ 
    fprintf(dout4, "%d\n", e_scatter[i]); // save one method call 
    // fprintf(dout2, "%f\n", e_scatter[i]); 
}; 
fclose(dout4); 

:ofstreamのは、ファイルの書き込みのSTL-方法です

ofstream dout4("escatter.dat", std::ofstream::out); 
for (int i = 0; i <= n; i++) 
{ 
    dout4 << e_scatter[i] << std::endl; 
}; 
dout4.close(); 
+0

ありがとうございました!私はインターフェイスを使って最初のプログラムを作った後、最適化をしたかったのです。デバッグの問題が他のユーザーによって解決されたので、これらの最適化が私を助けます!私は、ofstreamがfopen/fprintfよりずっと遅いことを知ったが、他の部分はおかげで助けになるだろう! – Kazkek

+0

フラッシュを減らすために、 'dout4 << e_scatter [i] <<" \ n ";'を試すことができます。 – lexx9999

+0

STLはありません。そして私は、少ないコードの代わりに多くのコードを実行すると、より良いパフォーマンスが得られると信じている理由は全くありません。 C++ストリームは本質的に直接ファイルアクセスよりも遅い。 – IInspectable