2010-05-31 4 views
1

내가 CUDA를 사용하여 다음과 같은 알고리즘을 구현하는 방법을 생각하기 위해 노력하고있어 큰 막대 그래프로 데이터를 축적 : 각 복셀에 대해 내가 인덱스를 계산CUDA는 : 수레

복셀의 큰 볼륨에서 작업을 i 값은 c입니다. 계산을 수행 한 후에 수행해야합니다 histogram[i] += c
c은 부동 소수점 값이고 히스토그램은 최대 15,000 개의 저장소를 가질 수 있습니다.

이 방법을 CUDA를 사용하여 효율적으로 구현할 방법을 찾고 있습니다. 첫 번째 명백한 문제는 내가 사용하고있는 컴퓨팅 기능 1.3에서 부동 소수점 atomicAdd()을 수행 할 수 없다는 것입니다. 어떻게 안정적으로 누적 될 수 있습니까?

This example by nVidia 다소 다소 단순합니다. 히스토그램은 공유 메모리에 저장되며 (크기 때문에 수행 할 수 없음) 정수 만 누적합니다. 이 접근법을 제 경우로 일반화 할 수 있습니까?

답변

0

atomicAdd()를 사용하여 외부 메모리에 직접 히스토그램을 작성하는 것은 매우 비효율적입니다. 히스토그램의 범위에 따라 원본 데이터를 여러 번 통과시키고 공유 메모리에서 부분 히스토그램을 업데이트 한 다음 각 패스 후에 부분 히스토그램을 쓸 수 있습니다. 입력 데이터를 통해 많은 수의 패스를 만들 필요가없는 한 훨씬 더 효율적이어야합니다. 분명히 필요한 패스 수를 최소화하기 위해 사용 가능한 공유 메모리의 한계에 따라 부분 히스토그램을 최대한 크게 만들고 싶을 것입니다.

1

두 단계 접근 방식이 가장 좋습니다. 하나의 보셀의 하위 집합에 대해 여러 히스토그램을 작성하고 전역 히스토그램을 합계로 계산할 수 있습니다.

N 개의 보셀이 있다고 가정하면 먼저 Mx15000의 전역 장치 메모리를 만듭니다 (여기서 M은 모두 <이지만 N 코어가 사용 중임)

각 스레드 색인에 대한 복셀의 N/M 번호의 히스토그램을 계산하려면 cuda kernal을 실행하십시오. 모든 스레드가 완료된 후 이제 최종 히스토그램에 대해 M 막대 그래프를 더한 다른 cuda 커널을 실행할 수 있습니다.

+0

이것은 유망한 접근 방법처럼 보이지만 두 스레드가 같은 셀에 동시에 쓰지 않도록하려면 어떻게해야합니까? – shoosh

+0

각 스레드는 두 번째 커널을 사용하여 합산 한 자체 히스토그램을 갖습니다. 걱정할 필요가있는 것은 합계가 발생하기 전에 모든 스레드가 완료되었는지 확인하는 것입니다. – sjchoi

관련 문제