2017-03-21 2 views
1

저는 OpenCL (JOCL을 통해)을 사용하여 광선 행진을위한 거리 계산에서 최소값을 찾습니다. 의사 코드는 다음과 같을 것입니다 :배열의 최소 OpenCL 찾기 인덱스

Start with a point in 3d space. 
There are a number of functions to calculate distances 
    to that point from various other points. 
    These may be rather complex (transforms, csg etc). 
Calculate all of the distances, perhaps into an array 
Get the index of the minimum distance in the array.. 
Use that index to do up other stuff (pigmentation etc). 

내 구현은 다소 허울입니다. 현재 거리 계산을 병렬 처리하지 않지만 원하는 것은 있습니다. 이유는 다음과 같습니다.

최소 거리를 확보하기는 쉽지만이 색인을 검색하는 것은 분명하지 않습니다. 나는 거리를 반복하고 현재 최소값과 그 인덱스를 추적하는 것을 끝내지 만 이것은 병렬 환경에서의 쓰레기 다.

기본적으로 팁을 사용하여 나를 올바른 방향으로 인도 할 수 있습니까, 아니면 완전히 잘못된 트리를 짖는 지 말해 줄 수 있습니까? (예 : 이것은 CPU 작업입니까?)

고마워요!

+1

thread-1은 두 쌍 사이의 거리를 비교할 수 있습니다. thread-2는 다른 두 쌍에 대해서도 동일한 작업을 수행 할 수 있습니다. 그런 다음 두 스레드 간의 동기화 후 단일 스레드가 두 결과를 확인하고 최소 최대 값을 선택할 수 있습니다. 이제 크기가 N 인 경우 동기화 수는 LogN이 될 수 있으며 첫 번째 단계의 최대 스레드 수는 N/4 일 수 있습니다. 감량 같아. N/4 코어가있는 경우 LogN 동기 포인트 만 - 반복 - 의사주기가 필요합니다. –

+0

그러나 배열이 정렬되지 않은 경우 무차별 대입 O (n^2) 검사가 필요할 수 있으므로 N/4 코어 시스템에서 N * Log (N) 의사 사이클이 필요합니다. –

+0

@huseyintugrulbuyukisik 감사합니다. 시도 해봐. 그것은 정렬이 필요하지 않으므로 감소입니다. 단지 분과 그것의 지수를 고르는 것입니다. 감사! –

답변

0

로우 엔드 그래픽 카드 인 RX550으로 테스트되었습니다.

1 백만 요소 분() 함수 : 랜덤 값과 자신의 인덱스와 인덱스 요소

__kernel void test(__global float * data,__global int * index) 
{ 
    int id=get_global_id(0); 
    float d1=data[id]; 
    float d2=data[id+get_global_size(0)]; 
    float f=fmin(d1,d2); 
    index[id]=select(index[id+get_global_size(0)], index[id], fabs(f-d1)<=fabs(f-d2)); 
    data[id]=f; 
}"); 

초기화 데이터 요소. PCI-E 2.0 배속 통해 GPU하기

업로드 데이터 및 인덱스했다 : 3.0 MS

컴퓨팅 글로벌 범위 = 512K, 256K, 128K, ...이 1 ​​(logN 단계)했다 : 0.3 밀리

데이터 [0] 및 색인 [0] 다운로드 중 : 0.002 ms

이것은 가장 빠른 구현이 아닐 수있는 간단한 버전입니다. 빠르게 얻기 위해서는, 작업 그룹 레벨 서브 감소 첨가 될 수

  • work_group_scan_inclusive_min (X)
  • 오픈 CL 2.0 대한 수를 줄이기 위해 오픈 CL 1.2 ~ 대한

를 reductionArray [256] 플로트 __local 커널 엔큐 명령을 사용하여 백개 만에 작업을 완료 할 수 있습니까? 마이크로 초.