2015-01-22 5 views
1

내 프로그램에서는 큰 데이터 세트를 구문 분석하기 위해 Boost-Spirit-Qi를 사용합니다. 입력 데이터는 순차 레코드입니다. 구문 분석의 효율성을 높이기 위해 TBB를 사용하려고합니다. 다음 병렬 처리하기위한 과정은 다음과 같다 :부울과의 파싱 병렬화 : TBB :: spirit :: qi

typedef map<string, data_struct_t> mdata_t; 
vector<string> text; 
mdata_t data; 

parallel_for(blocked_range<size_t>(0, input.size(), gs), 
        [&] (blocked_range<size_t>& r) { 
     data_struct_t cs; 
     mdata_t cr; 
     string s; 
     for(size_t i=r.begin(); i<r.end(); i++) { 
      s = text[i];   
      Parser::task1(s, cs); 
      Parser::task2(s, cs); 
      Parser::task3(s, cs); 
     .... 
      Parser::task8(s, cs); 
      cr.insert(std::make_pair(cs.title, cs)); 
     } 
     data.insert(cr.begin(), cr.end()); 

}, ap); 

내 프로그램은 CPU (CPU (2), 코어 (16))의 10 %를 사용하고, 코어 (8)에서 작동한다. 나머지 8 코어가 사용되지 않는 이유는 (단일 프로세서) 이해가되지 않습니다. 이 작업을 올바른 알고리즘 병렬 처리로 안내해 주셔서 감사드립니다.

감사합니다.

스탠

답변

0

귀하의 input.size() 작은 수 있습니다 또는 gs 병렬 처리의 충분한 양의 생성을 방지하기 위해 너무 큽니다. 그렇지 않은 경우 스레드 수가 문제가되면 프로그램 시작시 프로세스 (선호도) 마스크와 TBB가 초기화되는 방식을 확인하십시오 (예 : 스레드 수가 적은 tbb::task_scheduler_init).

CPU 사용률은 작업이 IO 바인딩 (예 : 파일 읽기) 될 때 예상됩니다. 하나의 병렬 반복을 완료하는 데 필요한 시간이 다른 반복과 많이 다를 수도 있습니다. 이 경우, 모든 스레드가 작성되기 전에 작은 반복이 완료 될 수 있습니다.

당신은이 std::map 이후 data.insert 버그가 동시 변경에 대한 안전하지 않습니다 :

조언이 (정확하게 속도 향상을 측정 할 경우에는 수동으로 모든 스레드가 작동 할 때 기다려야한다). cr에서 수집 된 부분 결과를 다른 스레드에서 병합하려면 tbb::concurrent_unordered_map 또는 tbb::parallel_reduce을 사용하십시오.

패턴이 Parser::task1(s, cs); ... Parser::task8(s, cs); 인 경우 작업이 전역 상태를 공유하지 않는 경우 병렬 처리 할 수도 있습니다. 이러한 독립적 인 작업 체인에 대한 파이프 라인 유형의 병렬 처리를 활성화하는 tbb::parallel_pipeline을 참조하십시오.

+0

많은 분들께 감사드립니다. 몇 가지 의견을 들으면 나는 동의 할 수 없다. 예를 들면 : imput.size = 100000, gs는 1-10000 범위에서 테스트되었으므로 몇 가지 분명한 이유 때문에 작업을 사용하지 마십시오. 컨테이너를 병행 축소 또는 병행하는 데 사용해야 함을 동의합니다. 예제가있는 웹 사이트에 대한 링크를 알고 계십니까? – stansy

+0

@stansy, 방금 생성 한 작업의 범위와 개수가 아닌 경우 동작의 모든 가능성을 다룰려고했는데, 내부 작업량이 적거나 또는 마스크를 통해 제공된 스레드 수에 대한 제한이 있거나 TBB API. 여전히 스레드 수는 위에서 다룬 CPU 사용률과 별개입니다. TBB 패키지 및 참조 페이지에서 예제를 찾을 수 있습니다. – Anton

+0

고마워요 @Anton. 몇 가지 테스트 후에이 문제에 대한 해결책을 찾았습니다. 결론은 간단합니다. 항상 반복자를 인덱스로 사용하지 마십시오. TBB 컨테이너를 사용하여 복잡한 계산을 사용하지 않는 경우 계산 시간이 크게 향상되지 않습니다. 동일한 성공으로 표준 컨테이너를 사용할 수 있습니다. – stansy