2

asio のバッファの参照セマンティックが使いにくいことがわかりました。ユーザーはデータをヒープに割り当てる必要がありますが、小さなサイズのデータ​​(たとえば100バイト)の場合、スタックに割り当てて数回コピーします(asioを使用する場合、コピー回数は3回未満になると思います)よりもはるかに高速になります新しい操作を呼び出します。例:

class MyData {
    std::vector<char> data;
};

void hander(Request req) {
    MyData d;
    async_write(buffer(d.data)...);
} // oops, d was destroyed, but the actual write have not execute

// this is ok, but awkward and poor performance if data is very small
void hander(Request req) {
    shared_ptr<MyData> d(new MyData());
    async_write(buffer(d->data)...bind(&X::handle_write, this, d);
}
void handle_write(shared_ptr<MyData> s) {
}

asio がディープコピーを実行できるバッファを提供していないのはなぜですか? パフォーマンスのためにコピー時間を節約できますが、アプリケーションが膨大な数の小さなデータを送信する場合、パフォーマンスは低下するはずです

そのドキュメントでは、接続オブジェクトにはデータを保持するために使用されるメンバーがありますが、ほとんどのアプリケーションでは、データ メンバーは十分ではありません。アプリケーションがいつでもデータを書き込むことができる場合 (HTTP などの半二重プロトコルは好まない)、キューを使用する必要があります。そうしないと、次の書き込みによってデータが上書きされる可能性があります。したがって、キューが Queue の場合は new を呼び出す必要があり、キューが Queue の場合はコピーする必要があります

4

2 に答える 2

3

Boost.Asio のバッファ タイプは、実際のメモリをどこに割り当てる必要があるかについての要件を課しません。それが表すメモリが連続している必要があるだけであり、連続していない場合は、バッファシーケンスを使用する必要があります。

Boost.Asio はbuffer_copy、あるバッファまたはバッファ シーケンスから別のバッファへのディープ コピーを実行するために使用できるものを提供します。純粋な憶測ですが、Asio は次の理由により、基礎となるメモリを所有するバッファを提供しない場合があります。

  • メモリ使用特性は、アプリケーションによって異なります。使用する適切なデフォルトの割り当てまたは所有戦略があるかどうかは明らかではありません。
  • boost::buffer()boost/std::arrayさまざまなタイプ (raw メモリ、c-array 、、、std::vectorおよび)から Boost.Asio バッファを作成する便利な方法を提供しますstd::string。これらのタイプの一部は、割り当てをカスタマイズする方法と、ディープ コピーを実行する方法 (コピー コンストラクター、代入などstd::copy) を既に提供しています。
  • Boost.Asio 操作は、 など の実際のタイプではなく、MutableBufferSequenceboost::asio::mutable_buffersなどのバッファ シーケンスの概念/タイプ要件に実装されます。したがって、ユーザーは、型の要件を満たしている限り、独自の型とメモリ管理を自由に使用できます。これは参照カウントバッファの公式の例です。

プロファイリングを行い、割り当てとコピーがボトルネックであることを特定したら、特定の問題に対処するために設計された手法を採用することを検討してください。

  • メモリ プールを使用すると、メモリを解放してフリー ストアに戻すのではなく、メモリを再利用できます。
  • 場合によっては、参照カウント バッファーを使用すると、ディープ コピーを実行する必要がなくなることがあります。公式の例またはを使用することを検討してくださいboost/std::shared_ptr。これらは、カスタム デリーターを使用することで、プールによって管理される型で使用することもできます。
  • 一意の所有権の場合、std::unique_ptrおよび/または移動セマンティクスにより、不要なディープコピーも削除される場合があります。
于 2013-06-27T15:49:07.937 に答える
0

ASIO はそのようなバッファ クラスを提供していませんが、独自のバッファ クラスを作成することは可能です。また、Buffersの例には、そのようなクラスの実装があります。

パフォーマンスを向上させるために、プールを編成することができます。たとえば、WebSocket++ライブラリは独自のメッセージ プールを使用します。

于 2013-06-27T15:20:50.100 に答える