1

Fortran の最適化 (おそらく一般的なプログラム) について質問があります。

基本操作を実行するには、ベクトル全体または行ごとの 2 つの方法があります。

x = array(:,1)
y = array(:,2)
z = array(:,3)

x1 = floor(x/k) + 1
y1 = floor(y/k) + 1
z1 = floor(z/k) + 1

また

do i = 1:n
   x1(i) = floor(x(i)/k) + 1
   y1(i) = floor(y(i)/k) + 1
   z1(i) = floor(z(i)/k) + 1
end do

1 億のエントリがあるため、ループ上で openmp を実行できますが、うまくいくかどうかはわかりません。ループ内またはループ外で実行する方が速いでしょうか。経験と常識は、外でやれと言います。プログラムには他にもコンポーネントがありますが、変換する x、y、z 値が非常に多いため、ほとんどの時間が新しいベクトル x1、y1、z1 の作成に費やされていることがわかりました。

4

2 に答える 2

2

実行速度が気になる場合は、一時配列と思われるスライスxy、およびを省いたバージョンのコードをプロファイルすることをお勧めしますz。それらを作成するには、マシンのメモリの周りに多くのものをコピーする必要があります。あなたは単に書くことができます

x1 = floor(array(:,1)/k) + 1
y1 = floor(array(:,2)/k) + 1
z1 = floor(array(:,3)/k) + 1

コンパイラはコピーを作成せずにこれを実行できるはずですarrayが、これは確認する必要があります。

質問に表示されていないコードの要素に応じて、 を宣言し、ポインターになり、次のように書くことさえできる場合がありx1ます。y1z1

array_over_k = floor(array/k) + 1
x1 => array_over_k(:,1)
y1 => array_over_k(:,2)
z1 => array_over_k(:,3)

どちらの方法で計算を行っても、計算を行う必要がありますが、配列の要素のコピーをすべて作成する必要がありますか?

于 2012-12-18T22:47:52.567 に答える
0

これは、メモリ帯域幅に制限されます。それらがメモリ内で分離している場合(つまり、いくつかの奇妙な非連続ポインタではない場合)、私は最初の方法に進みます。ただし、プロファイラーがないと簡単に間違ってしまう可能性があるため、試して測定することをお勧めします。また、OpenMPを実行することも、最初のバージョンに対して自動並列化を実行することもできます。

于 2012-12-18T18:35:15.940 に答える