2011-02-03 9 views
5

私のプロジェクトの1つでは、std::deque<T>::clear()へのコールが大きなボトルネックとして特定されました。専用スレッドでSTLをクリアする

私はそのための専用、優先度の低いスレッドでこの操作を移動することを決めた:

template <class T> 
void SomeClass::parallelClear(T& c) 
{ 
    if (!c.empty()) 
    { 
     T* temp = new T; 
     c.swap(*temp); // swap contents (fast) 

     // deallocate on separate thread 
     boost::thread deleteThread([=]() { delete temp; }); 

     // Windows specific: lower priority class 
     SetPriorityClass(deleteThread.native_handle(), BELOW_NORMAL_PRIORITY_CLASS); 
    } 
} 

void SomeClass:clear(std::deque<ComplexObject>& hugeDeque) 
{ 
    parallelClear(hugeDeque); 
} 

これは(VisualC++ 2010)正常に動作するようですが、私はすべての主要な欠陥を見落としているのだろうか。上記のコードに関するご意見をお待ちしております。

追加情報

SomeClass:clear()は、GUIスレッドから呼び出され、ユーザインタフェースは、呼び出しが戻るまで応答しません。一方、hugeQueueは、クリア後に数秒間そのスレッドによってアクセスされる可能性は低いです。

+0

デバッガを接続せずに実行しても速度が遅いですか? –

+0

STLコンテナ自体はスレッドセーフではありません。そのため、マルチスレッド環境のコンテナで操作を行う前に、コードで前提とする必要があります。 – DumbCoder

+0

はい。実際に使用しているdequeには何百万ものオブジェクト(intではない)が含まれています –

答えて

2

これは、ヒープへのアクセスがシリアル化されていることを保証する場合にのみ有効です。 Windows は、デフォルトでがプライマリヒープへのアクセスをシリアライズしますが、この動作をオフにすることは可能で、プラットフォームやライブラリにまたがって保持されるという保証はありません。したがって、スレッド間で共有されるヒープと、スレッドがアクセスするスレッドセーフであることが明示的に指定されていることに注意してください。

私は個人的には、割り振り/割り振りパターンを一致させるためのカスタムアロケータを使用することをお勧めします。ここでは、スレッドの作成には些細なオーバーヘッドがあります。

編集:GUI /ワーカースレッドスタイルのスレッド設計を使用している場合は、実際には、を作成し、管理する必要があります。

+0

@DeadMG:システムごとにシリアル化をオフにすることはできますか?これはコンパイル時の設定ですか? –

+0

このカスタムアロケータでは、専用ヒープを使用します。このヒープは、クリアするときに一度にすべての割り当てを解除します。 –

+0

@ダニエル:私が知る限り、実行時に設定を変更することができます。あなたのカスタムアロケータに関しては、割り当てパターンについては十分に分かっていませんが、非常に大きなオブジェクトと一連の割り当て解除がある場合は、ヒープ全体の割り当てを解除するだけの価値があります。もちろん、関連するオブジェクトを破壊する必要があります。 – Puppy

1

アプリケーションの全体的なパフォーマンスが向上するとは限りません。 Windowsの標準ヒープ(低フラグメンテーションヒープ)は、割り当て情報をあるスレッドから別のスレッドに頻繁に送信するためにレイアウトされていません。これは機能しますが、処理のオーバーヘッドがかなり発生する可能性があります。

ホードメモリアロケータのドキュメントは出発点であるかもしれないことに深いのですか: http://www.cs.umass.edu/~emery/hoard/hoard-documentation.html

あなたのアプローチは、しかし他のポスターが言及したものに加えてなど

+0

ご返信ありがとうございます。私の場合、ヒープは通常、スレッドAから1000分の1回アクセスされ、次にスレッドBから同じ量(Aによって割り当てられたオブジェクトの割り当てを解除する)となります。だから、私は頻繁に切り替えるつもりはありません。しかし、私は特定のアロケータで代替案をチェックします(アプリケーションの残りの部分はすでに独自の特定のメモリ管理ルーチンを実装して使用しています)。 –

0

を応答性を向上しますコレクションに含まれるオブジェクトにスレッド親和性があるかどうかを検討する必要があります。たとえば、シングルスレッドアパートメントのCOMオブジェクトは、この種のトリックに従わない場合があります。

関連する問題