2017-11-08 14 views
2

私のプログラムでは、何千回も呼び出される関数があります。この関数には1つの引数、長さ= 30000のbool値の配列があります。このboolの配列に基づいて、グローバルな2次元配列変数からいくつかの行をコピーして、ローカルの2次元配列を構築します。次に、ローカルの2次元配列の各列の平均を求めます。次に、ローカルの2次元配列内のすべての値を取り出し、それを第2のローカル2D配列を作成するために減算します。C++の2D配列の部分を別の2D配列にコピーする性能

プログラムは意図したとおりに実行されていますが、問題の関数を追加してからは時間がかかりすぎます。 2次元配列からデータのサブセットを取り出し、新しい2次元配列を作るより速い方法がありますか? 2次元配列の各値から列平均を減算するより速い方法がありますか?多分、私はベクトルを調べたり、関数の外にあるものを宣言したりするべきです...

ありがとう。

double FitValue(bool *X){ 
    int i,j,k; //loop index 
    int counter; 
    int numUsedVariables = 0; // 
    double sum; 
    //find number of selected variables 
    for(i=0; i<NUMVARIABLES; i++){ //NUMVARIABLES is a globally defined variable 
     if(X[i] == true){ 
      numUsedVariables += 1; 
     } 
    } 
    //declare matrix for variable subset  
    alglib::real_2d_array input; 
    input.setlength(NUMINDIVS,numUsedVariables); 
    //populate matrix for variable subset 
    counter = -1; 
    for(i=0; i<NUMVARIABLES; i++){ //NUMVARIABLES is a globally defined variable 
     if(X[i] == true){  
      counter++; 
      for(j=0; j<NUMINDIVS; j++){ //NUMINDIVS is a globally defined variable  
       input[j][counter] = genotype[i][j]; //genotype is global variable 
      } 
     } 
    } 
    //find the mean of each column 
    alglib::real_1d_array colMeans; 
    colMeans.setlength(numUsedVariables); 
    for(i=0; i<numUsedVariables; i++){ 
     sum = 0; 
     for(j=0; j<NUMINDIVS; j++){ 
      sum += input[j][i];  
     } 
     colMeans[i] = sum/NUMINDIVS; 
    } 
    //declare centered selected markers matrix 
    alglib::real_2d_array centeredInput; 
    centeredInput.setlength(NUMINDIVS,numUsedVariables);  
    for(i=0; i<numUsedVariables; i++){ 
     for(j=0; j<NUMINDIVS; j++){ 
      centeredInput[j][i] = input[j][i] - colMeans[i]; 
     } 
    } 
    //perform further analysis ... 
    //... 

} 
+1

よりもはるかに遅い実行されますソース列平均から直接ローカル配列に代入します。 – user4581301

+0

関数を小さなサブ関数に分割した場合、読みやすくなります。たとえば、各列の平均を求めるコードは、実際にはそれ自身の関数でなければなりません。 –

+0

サイズ「i * j」の1次元配列を作成し、それをマスク実装で2D配列として機能させることができます。 – Stephen

答えて

1

2次元配列が1列目の順序でアクセスされるため、コードが遅くなります。 CPUがメインメモリから数値を取得するたびに、一塊の数値がキャッシュにフェッチされます。 C/C++では配列の先頭に格納されています。必要な次の数値が次の行にある場合、キャッシュされたすべてのデータは無意味です。 CPUは次の番号をフェッチするためにメインメモリに戻る必要があります。メインメモリに行くのは、すでにキャッシュに入っているデータにアクセスするのに比べて非常に遅いプロセスです。
コードを高速で実行するには、データをキャッシュのやり方で最もアクセスしやすいように再編成する方法を考える必要があります。このコード
for(i=0; i<numUsedVariables; i++) for(j=0; j<NUMINDIVS; j++) centeredInput[j][i] = input[j][i] - colMeans[i]; あなたは、列合計の1次元配列に直接ソースから列を合計列の合計から手段を計算し、ローカル配列を作ることができるかもしれ
for(j=0; j<NUMINDIVS; j++) for(i=0; i<numUsedVariables; i++) centeredInput[j][i] = input[j][i] - colMeans[i];