for (int ir = 0; ir < nr; ir++)
{
td = 0;
md = 0;
for (int i = 0; i < nc; i++)
{
d[ir * nc + i] = func(nc, cH, vH, ir, i);
td += dist[ir * nc + i];
}
md = td/nc;
mdi[ir] = md;
}
나는 위의 코드를 가지고 있으며 GPU로 이식하려고합니다. 그리고 나는이 코드를 시도했다.Cuda로 이식하기
//get thread IDs
const int ir = blockDim.y * blockIdx.y + threadIdx.y; //nR
const int i = blockDim.x * blockIdx.x + threadIdx.x; //nC
int td = 0;
int md = 0;
d[ir * nc + i] = func(nc, c, v, ir, i); //out
td += d[ir * nc + i];
md = td/nc;
if (i % nc == 0)
{
mdi[ir] = md;//out
td = 0;
md = 0;
}
그러나 결과가 일치하지 않습니다. 내가 도대체 뭘 잘못하고있는 겁니까? 어떤 충고?
완전한 두 경우에 대한 lable 코드. 기대하고있는 결과와 실제로 얻은 결과를 나타냅니다. –
하나의 문제점은'td + ='입니다. 직렬 버전에서는 내부 루프 내에서이를 업데이트합니다. 즉, 루프의 반복 사이에 종속성이 있음을 의미합니다. 이러한 종속성은 병렬 처리 할 때 리팩터링되어야합니다. 당신이 시도한 것처럼 보이지만, 스레드 로컬'td' 변수를 만든 다음 그 변수에 한 번만 추가하면됩니다. 즉, 변수는 각 스레드에 의해 업데이트되지 않습니다. 이 특별한 문제에 대한 한가지 옵션은'td' 변수를 전역으로 만들고 그것을'atomicAdd()'로 업데이트하는 것입니다. 그것은 최적이 아닐 수도 있습니다. –
포팅하는 알고리즘의 유형을 설명하기 위해 제목과 본문에 뭔가를 추가 할 수 있습니까? 그 이유는 SO에 대한 질문이 OP보다 다른 사람들에게 잠재적으로 도움이되기 때문입니다. OP에게만 이익이되는 질문은 너무 현지화되어 있습니다. 질문의 의미는 문제가있는 사람이 같은 유형의 알고리즘을 포팅해도 검색에서 찾을 수 없기 때문에 질문에만 도움이됩니다. –