非常に非効率的なプログラムが与えられ、コードを最適化して実行速度を上げる必要があるという課題があります。これらの 2 つを除いて、私はそれらのほとんどを非常に高速に実行しています。1 つは基本的に 2 次元配列のすべての値を同じ値に設定し、もう 1 つは基本的に 2 つの 2 次元配列の値を交換します。そして、それが問題です。それらは最も多くの時間を占めていますが、非常に単純であるため、関数を壊さずにそれらを削減する方法がわかりません。そして、クラスの他の学生が途方もないスピードアップを得ているので、それらをより速く走らせることが可能であることを私は知っています. 問題の2つは次のとおりです。
fSetArray(int rows, int cols, float val)
{
int i, j;
F2D *out;
out = fMallocHandle(rows, cols);
for(i=0; i<rows; i++)
for(j=0; j<cols; j++)
subsref(out,i,j) = val;
return out;
}
唯一の重要な部分は、そこにある 2 つのループです。基本的に、特定の幅 (行) と特定の高さ (列) を持つ 2 次元配列があり、すべての値を val に設定しています。しかし、ループの 1 つを排除する方法はありません (ループを高速化するには、これが最善の方法です)。明らかな何かが欠けていない限り。列と行が同じ数である場合、これは非常に簡単になります。
他の機能は次のとおりです。
fDeepCopy(F2D* in)
{
int i, j;
F2D* out;
int rows, cols;
rows = in->height;
cols = in->width;
out = fMallocHandle(rows, cols);
for(i=0; i<rows; i++)
for(j=0; j<cols; j++)
subsref(out,i,j) = subsref(in,i,j);
return out;
}
out 配列は常に in 配列よりも大きいため、オーバーフローなどを心配する必要はありません。この関数は基本的には 2 つの配列の値を交換するだけですが、これも非常に単純であるため、これ以上減らすことはできません。
そして、誰かが並列化と言う前に、サンプルのサイズとサーバーのために、スレッドを作成するために必要なオーバーヘッドが実際にプログラムを遅くします。私はもう試した。これら 2 つの関数は短すぎるため、スレッドを作成して、1 つの並列処理の後でスレッドを強制終了するだけの価値はありません。
しかし参考までに、これは技術的には OpenMP プロジェクトであり、並列化を使用することになっていますが、これら 2 つの関数については、実際にはプログラム全体の速度が低下します。チェックするために並列 for ループでタイミングを計りました。
編集: アイデアをくれた皆さん、ありがとうございました! 私はそれを起動して実行し、今フルスピードです!