2

現在、プロジェクトに取り組んでおり、実行速度を向上させたいと考えています。私は並列コーディングにまったく慣れていません。私のプログラムには最初は6つのループがあり、それを3つのループに最適化することができ、実行時間は300%短縮されました。私が研究したことから、問題は索引付けにあると思います。前のループですでにparforを使用しましたが、インデックスはi = 1:vs_max-1でした。

次のコードでは:

for i = 1:vs_max-1
 for j = i+1:vs_max-1
  d = max(abs(X(i,:)-X(j,:)));
  DD = exp(-(d/r)^n);
  D(i,j) = DD;
  D(j,i) = DD;
  while (i~=vs_max)
    d2 = max(abs(X2(i,:)-X2(j,:)));
    DD2 = exp(-(d2/r)^n);
    D2(i,j) = DD2;
    D2(j,i) = DD2;
    break;
  end

 end
end

問題は、jがi値も必要とし、複数のスレッドがある場合、これらの値に複数アクセスできる2番目のループインデックスにあると思います。

上記のコードをより高速にするために、parforがプロンプトを表示したり、別のタイプのコード最適化を提供したりしないように、このループのインデックスを再作成するのを手伝ってくれる人はいますか?

私の投稿を読んでお答えいただき、誠にありがとうございます。

4

1 に答える 1

2

基本的に、上三角行列でインデックスを生成しています。の値がにi向かって進むにつれてvs_max-1、線はどんどん短くなっています。これは、動的な作業スケジューリングが実行されていない限り、複数のスレッド間でうまく分散されません(たとえばschedule(dynamic)、OpenMPに精通している場合など)。

物事を「フラット化」して単一のループを実行し、数学を使用して反復数を(i,j)ペアに変換できます。たとえば、考えられる解決策については、この質問を参照してください。十分なメモリがある場合は、可能なすべての(i,j)ペアの事前入力されたリストを使用して、それを使用して反復回数iをすばやく計算することもできます。j

ところで:計算の2番目の部分は奇妙に見えます。while常に実行され、さらに1回だけ実行されるループに入れるのはなぜですか(最初の反復後に到達して終了することはないi ~= vs_maxため、常にtrueです)。ivs_maxbreak

于 2012-06-21T13:32:06.290 に答える