6

最近、MATLABコードのプロファイルを作成しましたが、頻繁に使用される関数で次のように表示されてショックを受けました。

5.76  198694   58 persistent CONSTANTS; 
3.44  198694   59 if isempty(CONSTANTS) % initialize CONSTANTS

言い換えると、MATLABは198694年の関数呼び出しで約9秒​​を費やし、永続性を宣言し、CONSTANTS初期化されているかどうかを確認しました。これは、その機能に費やされた合計時間の13%に相当します。

永続変数は、MATLABで実際にそれだけのパフォーマンスの低下をもたらしますか?それとも、ここでひどく間違ったことをしているのでしょうか。

アップデート

@Andrew私はあなたのサンプルスクリプトを試しましたが、出力に非常に困惑しています。

time   calls  line
                6 function has_persistent
6.48  200000    7 persistent CONSTANTS 
1.91  200000    8 if isempty(CONSTANTS) 
                9     CONSTANTS = 42;
               10 end

私はbench()コマンドを試しましたが、サンプルマシンの中間範囲にあるマシンが表示されました。Intel(R)Core(TM)i7 CPU、4GBRAMでUbuntu64ビットを実行します。

4

1 に答える 1

9

これは、Matlab で永続変数を使用する標準的な方法です。あなたはすべきことをやっています。それには顕著なオーバーヘッドがありますが、タイミングは驚くほど高いようです。

これは、Windows XP x64 の 3.0 GHz Intel Core 2 QX9650 マシン上の 32 ビット Matlab R2009b で実行した同様のテストです。他のマシンおよびバージョンでも同様の結果が得られます。あなたのタイミングより約5倍速い。

テスト:

function call_has_persistent
for i = 1:200000
    has_persistent();
end

function has_persistent
persistent CONSTANTS
if isempty(CONSTANTS)
    CONSTANTS = 42;
end

結果:

  0.89  200000    7 persistent CONSTANTS 
  0.25  200000    8 if isempty(CONSTANTS) 

実行している Matlab のバージョン、OS、および CPU を教えてください。CONSTANTS は何によって初期化されますか? Matlab のbench() の出力は、あなたのマシンにとって妥当なように見えますか?

あなたのタイミングは高いようです。修正すべきバグまたは構成の問題がある可能性があります。しかし、Matlab コードを本当に速く取得したい場合、標準的なアドバイスはそれを「ベクトル化」することです。コードを再構築して、より大きな入力配列でより少ない関数呼び出しを行い、ループや制御の代わりに Matlab の組み込みのベクトル化関数を利用します。そもそも関数への 200,000 回の呼び出しを避けるためです。もし可能なら。Matlab は、関数またはメソッド呼び出しごとのオーバーヘッドが比較的高いため (いくつかの数値については、「MATLAB OOP が遅いか、それとも何か間違っているか」を参照してください)、個々の関数呼び出しを高速化する代わりに、リファクタリングして関数呼び出しを排除することで、より多くのマイレージを得ることができます。

マシンで他の基本的な Matlab 操作をベンチマークして、単に「持続的」で遅いように見えるかどうかを確認する価値があるかもしれません。また、この小さな call_has_persistent テスト スクリプトを単独でプロファイリングして、関数のコンテキストが違いを生むかどうかを確認してください。

于 2010-09-27T17:31:22.967 に答える