2012-09-05 3 views
2

큰 이미지를 처리하는 커널이 있습니다 (OpenCL 1.1, 데이터 형식은 image2d_t 임). 때로는이 이미지의 영역 만 처리하기를 원합니다. 분명한 해결 방법은 전역 워크 옵셋을 사용하는 것입니다. 나는 이것이 성능 향상을 가져올 것으로 기대하지만, 지금까지는 이 0이 아닌 오프셋을 가진 실행 시간을 악화시킬뿐입니다! 나는 이러한 결과를 얻을 이유 OpenCL 전역 작업 오프셋은 성능에 영향을 미칩니 까?

// Image is 4096x4096 pixels. Local work size is 8x8. 
// 
// Example A: 
globalWorkSize = { 4096, 4096 }; 
globalWorkOffset = { 0, 0 }; 
// Execution time is 38 seconds 
//  
// Example B: 
globalWorkSize = { 3296, 3296 }; 
globalWorkOffset = { 400, 400 }; 
// Execution time is 58 seconds <------------------ ?! 
// 
// Example C: Cropped image @ 3296x3296 pixels 
globalWorkSize = { 3296, 3296 }; 
globalWorkOffset = { 0, 0 }; 
// Execution time is 28 seconds 

누군가 설명해 주시겠습니까?

+1

커널을 볼 수 있습니까? (반드시 그 전부가 아니라 입력, 출력, 루프가있는 일반 구조 등 ...)? 여기에 갈 길이 많지 않습니다. – Thomas

+0

나는 그 문제를 보여주는 최소한의 샘플을 만들려고 노력할 것이다. – l33t

+0

64로 정렬 된 오프셋을 사용해 보셨습니까? 정렬되지 않은 것이 있으면 GPU 성능을 저하시킬 수 있습니다. –

답변

1

Lubo 안토 노프는 데이터 액세스 정렬이 성능에 중요한 것에 대해 권리입니다. 그러나 다른 매개 변수는 스트라이드 패턴으로 메모리에 액세스합니다. X = 400, Y = 400에서 시작하는 너의

예는 다음

. = item 
x = work item 
c = memory channel 
stride = 4096 between y_item=1 and y_item=2 and in this stride, 
some of memory channels are left in "." areas and unused 

    unused channel 
^
    | 
    c c c c c c c c c c 
    . . . . . . . . . . 
    . x x x x x x x x x 
    . x x x x x x x x x 
    . x x x x x x x x x 
    . x x x x x x x x x 
    . x x x x x x x x x 
    . x x x x x x x x x 
    . x x x x x x x x x 
    . x x x x x x x x x 
    . x x x x x x x x x 

당연히이 제 400 개 않는 픽셀에 더 많은 채널이 있지만 이들 채널들 중 일부는 다른 채널들보다 수에 작은 " x "작업 영역. 예를 들어 채널 2,3,4,5,6,7은 "x"에서 20 번 액세스되지만 채널 1은 25 번 액세스되어 다른 채널보다 더 많은 직렬화 된 액세스를 강제합니다.

높이 2의 거듭 제곱 스트라이드 메모리 액세스가 적은 메모리 채널/뱅크를 사용 스트라이드 영역 이외의 영역보다 스트라이드 메모리 채널 수가 다른 경우의 성능을 감소시킨다.


성능을위한 하드웨어의 Z- 순서 지원의 이점도 작업 영역의 왼쪽 가장자리에서 손상되었을 수 있습니다.


각 주사선은 GPU의 연산 유닛의 수의 정확한 배수가 아닌 경우

는, 동일한 컴퓨팅 장치가 Z-주문 액세스 및 기억 (L1 캐시에 마지막 주사선에서 데이터를 캐시되지 않을 수 있습니다에 대한 이웃을-액세스 가우시안 필터 같은 것들)

c = compute unit, S=selected compute unit for observation 
    kernel is accessing neighbour pixels too, for filtering, for example 

    gpu has 10 compute units 

    strided: L1 cache not hit 
    .......... 
    .cccSccccc 
    .ccccScccc 
    .cccccSccc 
    .ccccccScc 
    .cccccccSc 
    .ccccccccS 

    non-strided: pixel[y-1] is already in L1, cache hit, more performance 
    .......... 
    cccScccccc 
    cccScccccc 
    cccScccccc 
    cccScccccc 
    cccScccccc 

하지만이 보장되지는 작업 항목에 대한 그냥 본능은 GPU의 모든 핵심 똑같이 대신의 반복적 인 작업 분배를 통해로드 최대 핵심 직업에 대한 배포됩니다 작성 먼저 작성 두 번째로 채우고 세 번째 등을 채운다. 첫 번째 코어를 채우면 핵심 효율성은 좋지만 비어있는 핵심 코어는 더 많은 코어를 보유 할 수 있다는 장점이 있습니다. 또한 이것은 장거리 필터링 커널을 필요로합니다. 5x5 필터는 가장자리 픽셀에서만 이익을 얻었으며 51x51 필터는 여러 작업 그룹을 포함합니다.

1

이미지를 사용하는 것이 올바른 선택 인 것 같지만 항상 그렇지 않을 수 있습니다.

는 픽셀과 테두리 색상 처리에 대한 필요성 사이의 보간이 필요하지 않은 경우 다음 이미지를 통해 버퍼를 사용하는 것이 좋습니다 수 있습니다.

은 심지어 당신이 좋은 성능을 전반적으로 더 나은 성능을 제공 할 수 가장자리 지역과 버퍼를 다루는 별도의 커널을 가질 수 있습니다 당신과 함께 처리하는 보더 색상이있을 때.

이미지로 더 나은 성능을 얻는 이유는 한 번에 128bits를로드 할 수있는 몇 가지 아키텍처 지침에 메모리에서 한 번에 능력 하중 이상의 픽셀에서 온다.

실제 질문 왔을 때 내 생각에 hw는 오프셋 및 작업 ID를 사용하여 각 픽셀의 실제 좌표를 계산합니다.

관련 문제