4

特に遅いコードのデバッグにしばらく時間を費やし、MATLABプロファイラーによって完全に破棄されました。これは私には大きなバグのように見えるので、誰かがここで起こっていることに光を当てることができるかどうか疑問に思いました。

問題を引き起こすコードは次のとおりです。

function profiler_test

  %%% Create 20 files with random data

  count = 20;

  for i = 1 : count
    x = rand(3);
    save(sprintf('temp_file_%06d', i), 'x'); 
  end

  %%% Load them in a for loop

  xs = cell(1, count);

  tic;
  for i = 1 : count
    x = load(sprintf('temp_file_%06d', i), 'x');
    xs{i} = x.x;
  end
  toc

  %%% Load them in a for loop, but writing a small log file on the way

  tic;
  for i = 1 : count
    x = load(sprintf('temp_file_%06d', i), 'x');
    xs{i} = x.x;

    file = fopen(sprintf('temp_logfile_%d', i), 'w');
    fprintf(file, 'Success\n');
    fclose(file);
  end
  toc


end

最初のforループは0.239739秒かかり、2番目のループは4.411179秒かかります。

forここで、2番目のループの例に示されているように、結果ごとにログファイルを作成するというずさんなアイデアを認識していることを明確にする必要があります。これは、クラスターで実行していて、出力、関数の進行状況を安価に表示したかったのですが、これがボトルネックであることがわかりました。私はそれで大丈夫です。

ただし、私の問題は、MATLABプロファイラーが次のように言っているため、間違った行を最適化するために1日を費やしたことです。

         1   24   tic; 
         1   25   for i = 1 : count 
4.41    20   26     x = load(sprintf('temp_file_%06d', i), 'x'); 
        20   27     xs{i} = x.x; 
             28     
        20   29     file = fopen(sprintf('temp_logfile_%d', i), 'w'); 
        20   30     fprintf(file, 'Success\n'); 
        20   31     fclose(file); 
        20   32   end 
         1   33   toc

の行の最後の3行を実行するのにかかる時間全体が配置されloadます。私の実際のプログラムでは、loadは他のビットにそれほど近くなかったので、プロファイラーを信用しないことを決定するまで、それは私には起こりませんでした。私の質問は:ここで何が起こっているのですか?なぜこれが起こったのでしょうか。このような奇妙な動作に注意する必要がありますか?

私はMATLAB2011aを使用しています。どうもありがとう。

編集:私はいくつかの混乱、謝罪を引き起こしているようです。状況は次のとおりです。

  • 上に示した2つのforループは同じですが、2番目のループの下部に3行あり、反復ごとに一時ファイルに書き込みます。
  • 2番目のループの実行にはかなり長い時間がかかります。結論として、これらの最後の3行は速度の向上のせいです。それらが削除されると、コードは再び高速になります。
  • ただし、プロファイラーは、2番目のループの時間をこれらの最後の3つのステートメントに帰することはありません。代わりに、私のload関数呼び出し(最初のループとまったく同じ呼び出しで、より高速でした)が0.2秒ではなく4秒かかっていることがわかります。したがって、最後の3行存在すると、loadが遅くなるか(私はこれを無視しましたが、それは可能性もありますか?)、MATLABプロファイラーが誤って報告しているloadのに4秒かかっているのは明らかです

いずれにせよ、非常に奇妙なことが起こっているように私には思えます。

編集:自分で答えたようです。以下を参照してください。誤解を招くため、タイトルを変更しました

4

3 に答える 3

3

あなたの投稿にバグの証拠は見当たりません。

ループ全体が約4.111であり、プロファイラーは26行目が約であると示しています4.11

これは、他のすべての行を合わせた場合の所要時間が0秒未満であることを意味します0.01。したがって、各行の所要時間は四捨五入されたゼロ秒です。

私の推測では、ゼロは印刷されないだけであり、これを他の行のタイミングが調整されていないものとして解釈したと思います。

何かが足りないかもしれませんが、これまでのところ、MATLABによって提供される出力は一貫しているようです。

于 2013-03-13T14:22:20.350 に答える
3

実際、私はそれを解決したと思います。新しい行で追加の処理時間が発生しているという結論にジャンプするのは間違っていたので、私の質問は少し誤解を招くようになりました-プロファイラーは正しいです。loadただし、一時ファイルへの書き込みが遅くなる理由はまだわかりませんでした。私はこれを試すことを考えました:

file = fopen(sprintf('../temp_logfile_%d', i), 'w');

つまり、現在の作業ディレクトリではなく、親ディレクトリ内のファイルに書き込みます。これにより問題が解消され、非常に高速でした。その理由は、他の多くのディレクトリと同様に、現在のディレクトリが私のMATLAB検索パスにあるためだと思います。MATLABは、検索パス全体を調べる関数を使用するたびに、loadディレクトリが変更されているかどうかを確認し、変更されている場合は、ロット全体を再解析して、使用可能なファイルを確認すると思います。作業ディレクトリに新しいファイルを書き込むと、確かにこれが発生します。私の場合、検索パスの一部である作業ディレクトリにサブディレクトリのツリー全体があるため、これはさらに悪化した可能性があります。

とにかく、質問とは全く違う答えになってしまったことを見て申し訳ありませんでした。検索パス全体に依存する関数を使用する場合は注意してください。

于 2013-03-13T14:52:37.173 に答える
1

MATLAB 2012bのプロファイラーによって生成された次のレポートが表示されますが、バグはありません。 ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください

于 2013-03-13T14:32:53.900 に答える