19

既存のロギング ライブラリを拡張しています。これは 2 つの側面を持つシステムです。フロントエンドはタスクがログ メッセージを書き込む場所であり、バックエンドはアプリケーションがそれらのメッセージを異なるシンクに転送するリスナーを接続できる場所です。バックエンドは 1 つのハードワイヤード リスナーでしたが、現在は柔軟性のためにこれを拡張しています。このコードは、高性能(1​​ ミリ秒あたりの転送バイト数で測定) が非常に重要な設計および実装目標である組み込みデバイスでのみ使用されます。

パフォーマンス上の理由から、メッセージはバッファリングされ、転送はバックグラウンド タスクで行われます。そのタスクは、キューからメッセージのチャンクをフェッチし、それらをすべてフォーマットしてから、登録された関数を介してリスナーに渡します。これらのリスナーはメッセージをフィルター処理し、フィルター基準に合格したメッセージのみをシンクに書き込みます。

これを考えると、メッセージをN送信するための通知関数 (リスナー) を持つことになります。これはかなり古典的な問題です。ここで、2 つの可能性があります。メッセージをループしてから、メッセージをそれぞれに渡す通知関数をループします。MN*M

for(m in formatted_messages) 
  for(n in notification_functions)
    n(m);

void n(message)
{
    if( filter(message) )
      write(message);
}

または、すべての通知関数をループして、一度にすべてのメッセージを渡すこともできます。

for(n in notification_functions)
    n(formatted_messages);

void n(messages)
{
  for(m in messages)
    if( filter(m) )
      write(m);
}

どの設計がより多くのメッセージをタイム スライスごとに処理できる可能性が高いかについて、基本的な考慮事項はありますか? (この質問がリスナーのインターフェースをどのように決定するかに注意してください。これはマイクロ最適化の質問ではなく、パフォーマンスを妨げない設計を作成する方法に関する質問です。私が測定できるのはずっと後のことであり、リスナーのインターフェースを再設計するには費用がかかります。 .)

私がすでに行ったいくつかの考慮事項:

  • これらのリスナーはメッセージをどこかに書き込む必要がありますが、これはかなりコストがかかります。そのため、関数呼び出し自体はパフォーマンス面でそれほど重要ではない可能性があります。
  • すべてのケースの 95% で、リスナーは 1 つだけになります。
4

4 に答える 4

2

したがって、ここではいくつかの要因が関係します。

キャッシュ内のメッセージはどれくらい接近しており、どのくらいのスペースを占めていますか? それらが比較的小さく (数キロバイト以下)、近接している場合 (たとえば、他の多くのメモリ割り当てを行うシステムで、メモリが数秒間隔で割り当てられたリンク リストではない場合)。

それらが近くて小さい場合、メッセージが一緒にプリフェッチ/キャッシュされ、すべてのnリスナーとフィルター関数を呼び出すため、2 番目のオプションがより効率的であると思います3) 以前のメッセージの「キャッシュ スローアウト」が増える可能性があります。もちろん、これはリスナーとフィルター関数が実際にどれほど複雑であるかにも依存します。彼らはどのくらいの仕事をしていますか?各関数がかなりの量の作業を行う場合、どの順序で行うかはおそらくそれほど重要ではありません。

于 2013-06-27T18:09:21.370 に答える
0

一方が他方よりも優れた設計である「根本的な」理由はありません。ライブラリの使用方法に応じて、いくつかの非常に小さな速度の違いが生じる可能性があります。個人的には、リスナーを最初に、メッセージを 2 番目に繰り返すことを好みます。

通常、ハンドラー本体はかなり高速だと思います。同じコードを繰り返し呼び出すように、おそらくリスナーを外側のループとして反復処理する必要があります。間接呼び出し予測のようなものは、この方法ではるかにうまく機能します。もちろん、データ キャッシュを無駄に使用することになりますが、うまくいけば、各メッセージ バッファーは、L1 に簡単に収まるほど小さいものです。

また、リスナーに a を受け入れconst vector<message> &させて、独自の反復を行わせてみませんか? 彼らは、バッファリングが有益であることは何でも行うことができ、最後に高価な書き込みを 1 回だけ行うだけです。

于 2013-06-27T18:08:17.033 に答える