2017-02-12 1 views
2

글로벌 작업 크기가 로컬 작업 크기의 배수가 아니지만 OpenCL 프로그램을 작성하고 있습니다. OpenCL에서 전역 작업 크기는 지역 작업 크기로 나눌 수 있어야합니다. 그래서 읽은 해결책은 전역 작업 크기의 크기를 반올림하고 선택된 지역 작업 크기로 나눌 수 있도록 몇 가지 추가 작업 항목을 추가하는 것이 었습니다.글로벌 작업 크기를 로컬 작업 크기의 배수로 만들기 위해 추가 작업 항목을 추가하는 방법

예를 들어, 로컬 작업 크기가 4 및 글로벌 작업 크기라고이다 (62)이 더 많은 작업-항목을 추가

아이디어는 여기에있을 것입니다 (당신은 62 개 커널에 의해 그들에 수행 작업을해야 할 요소가) 단순히 유휴 상태로 설정하여 글로벌 작업 크기를 64로 만듭니다. 따라서 64가 4로 나눌 수 있으므로 모든 것이 잘됩니다.

유휴 작업 항목을 정확히 구현하는 방법에 대한 아이디어가 있습니까? 단순히 글로벌 작업 크기를 64로 늘리면 프로그램의 계산 결과가 변경되어 궁극적으로 잘못된 결과가 나오는 커널이 두 번 추가로 실행됩니다.

+0

당신은 확실히 만 스레드가 계산을 수행 할 수 있도록 커널 내부 바운드 검사를 추가해야 그의 글로벌 인덱스는 유효한 데이터 범위에 속합니다. – sgarizvi

답변

2

글로벌 작업 크기를 현지 작업 크기의 배수로 반올림하는 표준 방식입니다. 이 경우 커널 내부에 바운드 검사를 추가하여 작업 항목 만 유효한 데이터 범위 내에있는 계산을 수행하도록해야합니다. 실제 데이터 크기를 커널 매개 변수로 지정하고이를 글로 z 색인 항목과 비교하여 수행 할 수 있습니다. 예제 커널은 다음과 같습니다 :

__kernel void example_kernel(__global int* input, __global int* output, int dataSize) 
{ 
    int index = get_global_id(0); 

    if (index < dataSize) 
    { 
     /* 
     rest of the kernel... 
     */ 
    } 
} 
+0

대단히 고맙습니다. 커널 내부의 바운드 검사를 고려하지 않았습니다. – alairbyday

1

OpenCL 2.0 이후에는 더 이상 로컬 작업 크기의 배수로 구성된 글로벌 작업 크기가 필요하지 않습니다.

실질적인 성능 이점이없는 한 로컬 작업 크기를 NULL으로 두는 것이 좋습니다.

당신은 GWS을 내림과 에지 작업 iters 커널에서

gws = (old_gws/lws) * lws; 
leftover = old_gws - gws; 

을에 추가 처리를 할 수

if(get_global_id(0) == (get_global_size(0)-1)) 
    // do computation for rest of the work-items (leftover) 
관련 문제