0

これが「宿題をする」という質問にあまりにも似ている場合は、お詫び申し上げます。私は少し立ち往生しており、これが私の行き先です。これは私が書いたコードではありませんが、現在はメンテナンス中です。

悪い日には約 8 時間稼働するツールがあります。今日プロファイリングしました。実行時間の 91.4% が 1 つのサブ関数にあり、その中で 70% の時間がこの 1 行のコードに費やされます。これは、3 ~ 4 個のネストされた for ループ (避けられない) 内にあるため、プロファイルされた実行で実質的に 60000 回呼び出されます。

    testincrease = ones(183,3021)*.02;
    cRange = (0:177)'; %fix broken syntax highlighting --> '
    pRate = ones(183,3021)*.02;
    lengthA = 0;
    lengthP = 178;
    nSim = 3021;

    tic
    for i  = 1:100
    v_F = @(adj_N,adj_I) (((1+ adj_I+ testincrease(cRange+1,:))./(1 + adj_N + pRate(cRange+1,:))).^...
                repmat([cRange+0.5],[1 nSim]))...
                ./ ...
                (repmat(((1+adj_I+testincrease(lengthA+1,:))./(1 + adj_N+ pRate(lengthA+1,:))), [lengthP 1]).^...
                repmat([repmat(cRange(1), [lengthP 1])], [1 nSim]));
    v=v_F(0,0);
    end
    toc

現在のアイデア:

おそらく、Repmat の代わりに bsxfun を使用できると思います (現在それを試しています)。

cRange(1) = 0 の場合 (テスト データの一部 (ここに示した部分) でそうであったように)、後半は単純に 1 で割っています。これは、コストが高く無意味な計算です。したがって、不必要な計算を避けるために、これを「if」句で囲みたいと思います。

別の言語を呼び出す - これは私にとってまったく新しいことです。おそらく試してみるつもりです。Java に簡単にアクセスでき、mex ファイルも作成できるようです。後者の場合、この 1 行だけでなく大量のコードを書き直さない限り、データを渡すオーバーヘッドは非常に高くつくと思います。

他にご意見がございましたら、お聞かせいただければ幸いです。そうでない場合は、さらに調査を続けます。

編集:関数 repmats の最終行は完全に不要であることに気付きました.^ 行列に変更する必要なくスカラー値で

二次編集:これはこれまでの様子です。30% の節約。

tic
for i  = 1:100
    if cRange(1) == 0

        v_F = @(adj_N,adj_I) bsxfun(@power,((1+ adj_I+ testincrease(cRange+1,:))./(1 + adj_N + pRate(cRange+1,:))),cRange+0.5);

    else
        v_F = @(adj_N,adj_I) bsxfun(@power,((1+ adj_I+ testincrease(cRange+1,:))./(1 + adj_N + pRate(cRange+1,:))),cRange+0.5)...
            ./ ...
            (repmat(((1+adj_I+testincrease(lengthA+1,:))./(1 + adj_N+ pRate(lengthA+1,:))).^cRange(1), [lengthP 1]));

    end
    v=v_F(0,0);
end
AllChange = toc;

しかし、何らかの理由で、2011a で高速化された bsxfun の変更により、コンパイルする 2008 年には速度が低下します。バガー。

4

1 に答える 1

2

提案 1 - repmat なしでコードを書き直してみてください:

repmat大量のメモリ割り当てとメモリコピーを作成します...そのため、コードを書き直して同じ機能を使用しない場合repmat、速度が大幅に向上する可能性があります。(参考までに...コードの1行には4つrepmatの関数呼び出しがあります...呼び出しの1つにrepmatINSIDErepmatがあります...それは恐ろしく遅くなります。)

提案 2 - ワンライナーを書き直してみてください:

この大規模なワンライナーを複数の行に書き直してください。次に、プロファイラーを再実行します。これにより、速度低下の原因をより明確に把握できます。その後、そのコードを修正できます。(プロのヒント: さまざまな理由 (読みやすさ、デバッグ、パフォーマンスなど) により、大量のワンライナーをコードに含めるのが最善ではない場合があります) – Trevor Boyd Smith 17 秒前編集

提案 3 - 並列化を利用する:

1 行のコードのほとんどの操作は並列化できると思います。そのため、まず Matlab の並列ツールブーを試すことをお勧めします。それでもまだ十分に高速でない場合は、Jacketなどの外部のサードパーティ製 Matlab GPU アクセラレーション ソフトウェア パッケージを介して GPU アクセラレーションを使用してみてください。


(免責事項:これらは一般的なヒントです...私はまだこれらのいずれも試していません...しかし、時間があれば試してみます。)

于 2012-07-20T17:46:17.140 に答える