1

私は、最も時間のかかる関数を特定するために私のmatlabコードをプロファイリングしました。それらはほとんどが勾配であり、このファイルのKron matlab関数は、それらをcudaカーネルに書き込み、次にPTXしてmatlabから呼び出します。アイデアや記事は何でも良いでしょう.またmbの計算は分離可能であるように思われ、異なるブロックに割り当てるのに適した候補になります。ファイルからのコードのスナップを次に示します。

i2w=g0*aff(i2,a0);
[ix,iy]=grad(i2w);

ix=ix.*region;iy=iy.*region;
ix2=ix.^2;iy2=iy.^2;ixiy=ix.*iy;
it=i1-i2w;

m1=sum(sum(kron(ones(1,limy)',(1-centx:limx-centx).^2).*ix2));
m2=sum(sum(kron((1-centy:limy-centy)',(1-centx:limx-centx)).*ix2));

ps: 私は最近NVMEXについて読んだので、そのようなコードでのこのオプションについて少し助けてください。

4

1 に答える 1

1

これは 1 回の投稿で答えるには長すぎる質問ですが、2 つのヒントを紹介します。

CUDA コードの作成とテストに約 2 週間を費やすほど、このコードのパフォーマンスに依存している場合は、Matlab コードを高速化するための私のアプローチについてお話ししましょう。

ヒント 1:

問題の関数を (matlab で) そのような方法で書き直すことから始めて、ループ、メモリ アクセス、および CUDA マニュアルにある基本的な関数 (加算、乗算など) のみを使用します。 -コード

    function result_array = MyFunctionToParallelise(constants,source_arrays)
    for x_idx=xcoords
     for y_idx=ycoords
      local_result=inner_function(x_idx,y_idx,constants,source_arrays(x_idx,y_idx));
      store(local_result to result_array(x_idx,y_idx));
     end
    end

あなたがそれを行い、あなたの "inner_function" が並列化可能である (他の local_results から独立しており、x_idx、y_idx などの任意の順序で取得できる) 場合、あなたは家にいます!

  1. 「inner_function」を C で記述し (C と MEX を知っていますよね?)、それがコンパイル可能であること、正しい結果を返すこと、および内部 y_idx の通常のループと外部 x_idx ループの OpenMP 化されたループを使用して mex ファイルで動作することを確認します。 . そうすれば、4 倍の加速が得られることがよくあります。(4 コア CPU での openMP のため)。ツールボックスやその他の有料のものは必要ありません。デフォルトで Matlab と MEX に含まれています。

  2. 「inner_function」の CUDA ランチャーを作成します。市販のツールボックスは必要ありません。これは簡単な部分です!「for ループ」をスレッドとブロックに置き換えるだけです。. . . これを、以前は通常の関数を使用していた mex ファイルに挿入します。このステップでは、C に対して 10 倍から 100 倍の加速が期待できます。

このアプローチに従うと、小さなステップごとにデバッグして正確性を検証できます。私の経験では、バッファ ポインタとバッファ サイズを管理するコードのタイプミスが、クラッシュや誤った結果の主な原因です。間違った結果を本当に速く取得しても意味がありません!.

ヒント 2:一部の複雑な関数 (kron など) の場合、入力と出力が固定サイズの場合、次のようなコンピューター代数システムを使用して、レジスターレベルで最適化された、線形で非反復的で分岐のないコードを取得できる可能性があります。 Wolfram Mathematica. このようなコードは GPU で超高速に実行されます。例: Mathematica の数式最適化コンパイラの使用例

于 2012-10-28T14:24:07.707 に答える