2012-05-14 2 views
0

플로트 * 메모리 블록에서 코드를 계산합니다. 이미지 작업을하고 있기 때문에 너비와 높이가 180, 180 회전으로 이루어져야합니다. 이 코드에서 유일한 병렬 처리 절차이므로 180 스레드 (1도 회전 당 1)를 시작합니다. 이미지를 회전시키고 매 회전마다 플로트 값을 얻습니다. 각 포인트에 현재 최대 값을 저장하는 또 다른 float * 블록이 있습니다.데이터 쓰기시 막대한 성능 손실

if(resultMap[i] < convrst) 
{ 
    resultMap[i] = convrst; 
    rMap[i] = (unsigned char)r0; 
    oMap[i] = (unsigned char)index; 
} 

resultMap에는 현재 가장 높은 값이 저장됩니다. convrst는 컨볼 루션의 결과이며, 현재 결과가 이전 결과보다 높으면 값을 저장하고 그 지점에 반경 (r0) 및 회전 (인덱스)을 저장합니다. r0는 원래 int이며 색인입니다. i는 0에서 imgsize-1까지가는 카운터입니다.

{} 부분에 지정이 없으면 전체 코드는 2 초 내에 끝나고 할당은 50 초가 걸릴 것입니다. 그 코드에서 동기화 문제를 피하기 위해 잠금을 해제했습니다).

왜 코드가 느리며 빨리 끝내려면 어떻게해야합니까?

+0

이 GPU를 실행하고 계십니까? – talonmies

+0

이것은 코어 i5-2410M 및 GeForce GT 540M이 장착 된 랩톱입니다. – SinisterMJ

+0

커널을 몇 개의 블록으로 실행하고 있습니까? 180 threads는 GT 540M과 같은 2 SM GPU에서도 ** 작은 ** (그리고 잘못된) 쓰레드 수입니다. – talonmies

답변

2

커널에 쓰기를 포함 할 때 속도가 느려지는 이유는 this question과 동일합니다 (OpenCL에 관한 것이지만 원리는 같습니다). NVIDIA 컴파일러는 "죽은"코드, 즉 공유 메모리 또는 전역 메모리 쓰기에 기여하지 않는 코드를 최적화하는 데 매우 공격적입니다. 따라서 질문에 표시된 것처럼 전역 메모리에 쓰기를 포함하지 않으면 컴파일러는 많은 양의 커널을 최적화하여 실행 시간을 대폭 줄이는 것입니다.

다른 질문에서와 마찬가지로, 진짜 질문은 커널이 50 초를 마치는 이유입니다. 코드와 실행 매개 변수에 대한 자세한 정보가 필요하지만 작성한대로 180 개의 스레드 만 실행하면 그 원인이 될 수 있습니다. GPU는 최고 성능과 같은 것을 얻기위한 것보다 훨씬 더 많은 병렬 처리가 필요합니다.

+0

고마워요, 저에게 고맙다는 계산 상 비싼 부품을 무시한다는 것이 내 생각이었습니다. 메모리에 쓰기를 생략합니다 (프로젝트 속성에서 Optimization을 시도했지만). 내가하는 일 : 이미지를 1도 단위로 180도 회전하고 회전 된 이미지에 회선을 계산합니다. 각 컨볼 루션에는 완전한 이미지가 필요하기 때문에 더 많은 동시 스레드를 얻는 다른 방법을 생각할 수 없습니다. 스레드 대신 블록을 작성하면 도움이됩니까? 현재 GPU와 CPU 모두 해당 작업에 약 50 초가 소요되며 CPU 버전은 전혀 스레드되지 않습니다 ... – SinisterMJ