インテル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のアロケータは問題ではありません。
作業者がアイドルである間に誰かがメモリを解放する方法を知っていますか?
テストを行いました(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に下がります。つまり、問題は再現されませんでした。 –
問題の再現を図っていただき、ありがとうございます。私もUbuntu 14.04でTBB 2017でテストしました。 私のシステムでは、修正したテストを実行しても、メモリ消費は行われません。しかし、 'malloc_trim'(以下の答えを参照)を呼び出した後、〜2MBになります。だから、システムに依存するようです。 –