2017-03-03 1 views
1

인텔 TBB 기능을 사용하는 스레드를 다시 사용할 때 높은 메모리 오버 헤드가 발생합니다. 스레드가 주어진 작업 부하를 완료하면 해당 메모리가 해제 될 것으로 예상했습니다. 그러나 스레드에 의한 작업 단위 실행 사이에 긴 일시 중지가 있더라도이 경우는 아닌 것처럼 보입니다. 우리는 15 개 작업자 스레드를 시작 예에서인텔 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로 바꾸고 std :: this_thread :: sleep_for로 boost :: this_thread_sleep 바꾸기) Visual Studio 2015 및 Intel TBB 2017 업데이트 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 할당자를로드한다는 것입니다. TBB 할당자는 libtbb.so 옆에있는 경우 메모리를 캐시합니다. env를 설정하여 tbbmalloc이 활성화되었는지 확인할 수 있습니다. var TBB_VERSION=1

TBB가 자체 작업자를 생성하는 동안 왜 작업자 스레드로 시스템을 초과 가입합니까?

+0

맞습니다.이 예제에서는 초과 구독합니다. 이 예제는 단지 복잡한 시스템의 간단한 추출물 일뿐입니다. 따라서 구현의 일부만 변경할 수는 없습니다. –