2017-03-03 9 views
1

インテルTBB機能を使用するスレッドを再利用すると、高いメモリオーバーヘッドが発生します。あるスレッドがあるワークロードを終了すると、それぞれのメモリが解放されることが予想されました。しかし、スレッドによる作業単位の実行の間に長い休止があっても、このようには見えません。私たちは15個のワーカースレッドを起動する例でint tbbメモリオーバーヘッド

int main() { 
    blocking_queue<size_t> command_input_queue; 
    tbb::atomic<size_t> count = 1; 
    //workers 
    std::vector<std::thread> worker; 
    for(size_t i = 0; i < 15; i++) { 
     worker.push_back(std::thread([&command_input_queue, &count](){ 
     while(true) 
     { 
      size_t size; 
      //wait for work.. 
      command_input_queue.wait_and_pop(size); 
      //do some work with Intel TBB 
      std::vector<int32_t> result(size); 
      for(size_t i = 0; i < result.size(); i++) { 
       result[i] = i % 1000; 
      } 
      tbb::parallel_sort(result.begin(), result.end()); 
      size_t local_count = count++; 
      std::cout << local_count << " work items executed " << std::endl; 
     } 
    })); 
    } 
    //enqueue work 
    size_t work_items = 15; 
    for(size_t i = 0; i < work_items ; i++) { 
     command_input_queue.push(10 * 1000 * 1000); 
    } 

    while(true) { 
     boost::this_thread::sleep(boost::posix_time::seconds(1)); 
     if(count > 15) { 
     break; 
     } 
    } 
    //wait for more commands 
    std::cout << "Wait" << std::endl; 
    boost::this_thread::sleep(boost::posix_time::seconds(60)); 

    //----!During the wait, while no thread is active, 
    //the process still claims over 500 MB of memory!---- 
    for(size_t i = 0; i < 15; i++) { 
    command_input_queue.push(1000 * 1000); 
    } 
... 

は、我々は問題を表示する例を用意しました。彼らはタスクを待ってtbb :: parallel_sortを行い、完了後にすべてのリソースを解放します。 問題は、すべてのタスクが処理され、すべての作業者が新しいタスクを待っても、プロセスはまだ500MBのメモリを要求しています。

valgrindの大量のようなツールでは、メモリが要求されている場所はわかりませんでした。 プログラムをlibtbb.soとリンクしました。だから、tbbのアロケータは問題ではありません。

作業者がアイドルである間に誰かがメモリを解放する方法を知っていますか?

+0

テストを行いました(blocking_queueをtbb :: concurrent_bounded_queueで置き換え、boost :: this_thread_sleepをstd :: this_thread :: sleep_forで置き換えました)、Visual Studio 2015とIntel TBB 2017 Update 2でコンパイルしました。テストではピーク時に〜500MBを使用しますが、メインスレッドが待機を開始するとすぐに〜1.7MBに下がります。つまり、問題は再現されませんでした。 –

+0

問題の再現を図っていただき、ありがとうございます。私もUbuntu 14.04でTBB 2017でテストしました。 私のシステムでは、修正したテストを実行しても、メモリ消費は行われません。しかし、 'malloc_trim'(以下の答えを参照)を呼び出した後、〜2MBになります。だから、システムに依存するようです。 –

答えて

2

通常は、deleteまたはfreeを呼び出した後、ヒープ割り当てメモリがOSに返されません。これを行うには、malloc_trimまたはアロケータ固有の関数を呼び出す必要があります。

+0

ありがとう!それが問題を解決しました。待ちの前に 'malloc_trim'を呼び出すとメモリ消費量が〜2MBに減少します。 –

2

TBBスケジューラは、割り当てられたアロケータにもかかわらずタスク割り当てをキャッシュしますが、500MBは説明しません。説明できることは、TBBが動的にTBBアロケータをロードすることです。そのメモリは、libtbb.soの隣にあると思います。 tbbmallocはENVのVAR TBBは、独自の労働者を作成しながら、あなたのワーカースレッドを持つマシンをオーバーサブスクライブなぜ私には奇妙に見えている何TBB_VERSION=1

を設定することによって活性化されるかどうかを確認することができますか?

+0

あなたは正しいです、私たちはこの例では加入過多です。この例は、複雑なシステムの単純化された抽出です。したがって、実装のその部分を単に変更することはできません。 –

関連する問題