4

私はプロファイリングの初心者です。タイミングの制約を満たすようにコードを最適化したいと考えています。私は Visual C++ 08 Express を使用しているため、プロファイラーをダウンロードする必要がありました。私はいくつかの検索を行いましたが、Sleepy に関する適切なチュートリアルが見つかりませんでした。ここで私の質問: 適切に使用するには? プロファイリングの一般的な考え方を把握したので、ボトルネックを見つけるために %exclusive に従って並べ替えました。まず、このリストの一番上にZwWaitForSingleObjectRtlEnterCriticalSectionoperator newRtlLeaveCriticalSectionprintfがあります、いくつかのイテレータ...そして、それらが60%のようになった後、最初の関数、子呼び出しの最初の位置が来ます。上記のエラーが発生する理由、その意味、およびこの重要な 60% にアクセスできない場合にコードを最適化するにはどうすればよいか、誰か説明してもらえますか? (「ソースファイル」の場合:不明...)。また、私の関数では、各行に時間がかかると思いますが、そうではありません。たとえば、算術演算や一部の関数にはタイミングがありません (未使用の「if」句にネストされていません)。最後に、超高速で実行できる回線があるにもかかわらず、何千回も呼び出されて実際のボトルネックになっていることを確認するにはどうすればよいでしょうか?

最後に、スリーピーは良いですか?または、私のプラットフォームの無料の代替品はありますか?

大変助かりました!乾杯!

        • アップデート - - - - -

プレーンな Sleepy と呼ばれる別のバージョンのプロファイラーを見つけました。一部のスニペットが呼び出された回数と行数を示します (重要なものを指していると思います)。だから私の場合.. KiFastSystemCallRetは50%かかります! 何らかのデータを待っているということですよね?その問題を改善するには、これらの複数の呼び出しの原因を追跡し、最終的にそれを削除/変更する適切なアプローチがありますか?

4

2 に答える 2

5

タイミングの制約を満たすようにコードを最適化したい

あなたはこのビジネスで根強い問題に直面しています。コードの実行時間を短縮する方法を見つけたいと考えていますが、あなた (および多くの人) は、さまざまな種類の測定を行うことが唯一の方法であると考えています (そして教えられてきました)。

少数派の見解があり、それを推奨しなければならないのは、実際の重要な結果(およびその背後にある鉄壁の理論) だけです。

「ボトルネック」がある場合 (そしておそらく複数ある場合)、30% のように、わずかな時間しかかかっていません。
発見されるバグとして扱ってください。

一時停止ボタンでプログラムをランダムに停止し、プログラムが何をしているのか、なぜそれをしているのかを注意深く見てください。それが取り除くことができるものかどうか尋ねてください。これを10回行います。平均して、3 回の一時停止で問題が発生します。本当に必要でない限り、2 回以上表示されるアクティビティは速度バグです。これは、問題のコストを正確に示すものではありませんが、問題の内容と、修正する価値があることを正確に示しています。プロファイラーは単なるプログラムであり、機会を構成するものについて広く考えることができないため、プロファイラーが見つけることができないこの方法で物事を見ることができます。

一部の人々は、それだけの価値があるほど十分なスピードアップが得られない可能性があると考えて、リスクを回避します。確かに、ペイオフが低くなる可能性はわずかですが、それは投資のようなものです。理論によると、平均して価値があり、高い見返りが得られる可能性もわずかにあります。いずれにせよ、リスクが心配な場合は、さらにいくつかのサンプルを試してみると不安が解消されます.

問題を修正した後、残りのボトルネックの割合は大きくなります。これは、ボトルネックは小さくなりませんでしたが、プログラム全体が小さくなったためです。そのため、プロセス全体を繰り返すと、見つけやすくなります。

プロファイリングに関する文献はたくさんありますが、実際にどれだけのスピードアップが達成されるかを実際に述べているものはほとんどありません。 これは、ほぼ 3 桁のスピードアップを伴う具体的な例です。

于 2012-11-30T15:05:48.757 に答える
2

ネイティブ C++ コードのプロファイリングには、GlowCode (Sleepy に似た商用製品) を使用しました。計測プロセスを実行し、プログラムを実行してから、ツールによって生成されたデータを確認します。計測ステップでは、すべてのメソッドのエントリポイントと出口ポイントに小さなトレース関数を挿入し、各関数が完了するまでにかかる時間を単純に測定します。

コール グラフ プロファイリング ツールを使用して、メソッドを「最も使用された時間」から「最も使用されていない時間」まで並べ替えてリストし、ツールは呼び出し回数も表示します。最も高いパーセンテージのルーチンにドリルダウンするだけで、どのメソッドが最も多くの時間を使用しているかがわかります。一部のメソッドは非常に遅いことがわかりましたが、掘り下げてみると、ユーザー入力またはサービスの応答を待っていることがわかりました。また、呼び出しのたびにいくつかの内部ルーチンを何千回も呼び出すため、長い時間がかかるものもありました。誰かがコーディング エラーを起こし、リスト内の各項目について大きなリンク リストを繰り返し歩いていましたが、実際には 1 回だけ歩いていました。

「最も頻繁に呼び出されるもの」から「最も呼び出されないもの」まで並べ替えると、どこからでも呼び出されるいくつかの小さな関数 (next()などのイテレータ メソッド) を見ることができます。ほとんどの場合、本当にきれいです。画面を描画するために 500 回呼び出されるルーチンで 1 ミリ秒を節約すると、その画面の速度が 0.5 秒速くなります。これは、どの場所に労力を費やすべきかを判断するのに役立ちます。

プロファイリングを使用するための 2 つの一般的なアプローチを見てきました。1 つは、いくつかの「一般的な」プロファイリングを実行し、一連の「通常の」操作を実行して、アプリの速度を最も低下させている方法を発見することです。もう 1 つは、特定のプロファイリングを行い、パフォーマンスに関する特定のユーザーの苦情に焦点を当て、それらの機能を実行して問題を明らかにすることです。

注意したいことの 1 つは、ユーザー エクスペリエンスやシステム スループットに測定可能な影響を与えるような変更に限定することです。人間の反応時間はそれほど速くないため、マウス クリックを 1 ミリ秒短縮しても、平均的なユーザーには何の違いもありません。レースカーのドライバーの反応時間は 8 ミリ秒台で、一部のエリート twitch ゲーマーはさらに高速ですが、銀行の出納係などの通常のユーザーの反応時間は 20 ~ 30 ミリ秒台です。メリットはごくわずかです。

1 ミリ秒の改善を 20 回行うか、20 ミリ秒の変更を 1 回行うと、システムの応答性が大幅に向上します。多くの小さな改善よりも 1 つの大きな改善を行うことができれば、安価で優れています。

同様に、1 秒あたり 100 ユーザーを処理するサービスを 1 ミリ秒短縮すると、10% の改善が得られます。つまり、1 秒あたり 110 ユーザーを処理するようにサービスを改善できます。

懸念の理由は、パフォーマンスを向上させるためにコーディングを厳密に変更すると、コードの構造が複雑になり、コードの構造に悪影響を与えることが多いためです。結果をキャッシュすることで、データベースへの呼び出しを改善することにしたとしましょう。キャッシュがいつ無効になるかをどのように知ることができますか? キャッシュ クリーニング メカニズムを追加しますか? すべての項目をループして実行中の合計を生成するのが遅い金融取引を考えてみます。そのため、runningTotal アキュムレータを保持してより速く応答することにします。行の空白、反転、削除、変更、数量の変更など、あらゆる種類の状況で runningTotal を変更する必要があります。これにより、コードがより複雑になり、エラーが発生しやすくなります。

于 2012-11-30T16:06:13.167 に答える