2012-10-23 3 views
0

IPP와 TBB를 결합하여 이미지 리사이징 알고리즘을 더욱 개선하려고합니다.인텔 IPP와 TBB를 결합

  1. 사용 IPP

내 문제는 내가 응용 프로그램을 코딩했다고하는 parallel_for 루프 내부 TBB와 TBB

  • 사용 IPP없이, 그리고 I : 나는이 작업을 수행 할 수있는 두 가지 방법이 있습니다 정확한 결과를 얻으십시오. 그러나 놀랍게도, 계산 시간은 결합 될 때 더 큽니다. 혼란을 피하기 위해 여기에 코드의 일부만 붙여 넣습니다. 그러나 필요한 경우 전체 코드를 제공 할 수 있습니다. 난 단지 IPP를 사용하는 첫 번째 경우를 들어, 코드 같은 것입니다 :

    ippiResizeSqrPixel_8u_C1R(src, srcSize, srcStep, srcRoi, dst, dstStep, dstRoi, 
    m_nzoom_x,m_nzoom_y,0, 0, interpolation, pBufferWhole); 
    

    을 (알고리즘의 기본은 이미지 크기 조정에 대한 인텔 TBB 샘플 코드에서 차용되었다)과 parallel_for 루프는 다음과 같습니다

    parallel_for(
        blocked_range<size_t>(0,CHUNK), 
        [=](const blocked_range<size_t> &r){ 
         for (size_t i= r.begin(); i!= r.end(); i++){ 
          ippiResizeSqrPixel_8u_C1R(src+((int)(i*srcWidth*srcHeight)), srcSize, 
    srcStep, srcRoi, dst+((int)(i*dstWidth*dstHeight)), dstStep, dstRoi, 
    m_nzoom_x,m_nzoom_y,0, 0, interpolation, pBuffer); 
         } 
        } 
    ); 
    

    srcdst은 원본 이미지와 대상 이미지에 대한 포인터입니다. TBB를 사용하면 이미지는 CHUNKS 파트로 분할되고 parallel_for는 모두 CHUNKS을 반복하며 IPP 함수를 사용하여 각 CHUNK의 크기를 독립적으로 조정합니다. dstHeight, srcHeight, srcRoidstRoi의 값은 이미지의 분할을 수용하도록 수정되며 src+((int)(i*srcWidth*srcHeight))dst+((int)(i*dstWidth*dstHeight))은 소스 및 대상 이미지의 각 파티션의 시작을 나타냅니다.

    분명히, IPP와 TBB는이 방법으로 결합 될 수 있습니다. 올바른 결과를 얻을 수는 있지만, IPP를 단독으로 사용할 때와 비교할 때 계산 시간이 단축된다는 것이 당황 스럽습니다. 어떤 일이 그 원인 일 수 있는지, 또는 어떻게이 문제를 해결할 수 있을까요?

    감사합니다.

  • +0

    이미지 크기가 너무 커서 병렬 처리를 이용할 수 없다고 가정합니다. 테스트 한 입출력 이미지의 크기는 어느 정도입니까? – yohjp

    +0

    그것은 처음 생각했지만, 원래 크기보다 몇 배나 큰 크기의 이미지를 테스트 한 후에도 개선되지 않았습니다. – SMir

    +0

    이것을 프로파일 링 해 보셨습니까? 어떤 플랫폼을 사용하고 있습니까? – Rick

    답변

    0

    일부 IPP 기능이 자동 멀티 스레딩 사용하는 것이 밝혀졌습니다. 이러한 기능을 위해 TBB를 사용하여 개선 할 수는 없습니다. 외관상으로는 ippiResizeSqrPixel_8u_C1R(...) 기능은 그 기능의 한개이다. 내가 모든 코어를 비활성화했을 때, 두 버전 모두 똑같이 좋았습니다.

    0

    코드에서 parallel_for의 병렬 처리 된 각 작업은 복수 ippiResizeSqrPixel 호출로 구성됩니다. 이 함수는 준비 단계 (예 : 설정 보간 계수 테이블)를 포함 할 수 있으며 일반적으로 런타임 효율성을 위해 한 번에 대용량 메모리 블록을 처리하도록 설계 되었기 때문에 한 번만 호출하는 직렬 버전과 비교할 때 의미없는 오버 헤드가 될 수 있습니다. (하지만 난 IPP 실제로 수행 방법을 모르겠어요.)

    을 내가 병렬 구조 다음을 제안한다

    parallel_for(
        // Range = src (or dst) height of image. 
        blocked_range<size_t>(0, height), 
        [=](const blocked_range<size_t> &r) { 
        // 'r' = vertical range of image to process in this task. 
        // You can calculate src/dst region from 'r' here, 
        // and call ippiResizeSqrPixel once per task. 
        ippiResizeSqrPixel_8u_C1R(...); 
        } 
    ); 
    
    +0

    코드에서 다르게 수행되는 작업을 파악하는 데 어려움이 있습니다. 루프의 본문을 완성 할 수 있습니까? – SMir

    +0

    기본적인 아이디어는 (1) IPP 함수를 호출하여 병렬로 수행되는 작업을 최소화하는 것, (2) 'parallel_for'의 이미지 덩어리를 세로로 분할하여 TBB가 함수를 호출하는 단위 인 청크 크기를 결정하게하는 것입니다. – yohjp