216
« dnia: Kwiecień 21, 2010, 15:11:12 »
Witam, mam taki problem, mam sobie taki kawałek kodu, jest to kernel CUDA, czyli funkcja wywoływana na GPU. Ten kod powinien obliczać przyspieszenie działające pomiędzy ciałem "i-tym" i "j-tym" ciałem. Jednak nie oblicza mi poprawnie tzn, zwraca a = 0. I moje pytanie co robię nie tak.
__global__ void ObliczPrzysp(float3 *pol, float3 *a, float *mass, int M, float GG, float pp)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
float4 delta;
float Q;
if(i<M && j<M)
{
if(i!=j)
{
delta.x = pol[i].x - pol[j].x;
delta.y = pol[i].y - pol[j].y;
delta.z = pol[i].z - pol[j].z;
delta.w = sqrtf(delta.x*delta.x + delta.y*delta.y + delta.z*delta.z + pp);
Q = GG*mass[j]/(delta.w*delta.w*delta.w);
a[i].x += Q*delta.x;
a[i].y += Q*delta.y;
a[i].z += Q*delta.z;
}
}
}
Ten sam kod napisany pod jedną iterację, tzn:
__global__ void ObliczPrzysp(float3 *pol, float3 *a, float *mass, int M, float GG, float pp)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
float4 delta;
float Q;
for(j=0;j<M;j++)
{
if(i!=j)
{
delta.x = pol[i].x - pol[j].x;
delta.y = pol[i].y - pol[j].y;
delta.z = pol[i].z - pol[j].z;
delta.w = sqrtf(delta.x*delta.x + delta.y*delta.y + delta.z*delta.z + pp);
Q = GG*mass[j]/(delta.w*delta.w*delta.w);
a[i].x += Q*delta.x;
a[i].y += Q*delta.y;
a[i].z += Q*delta.z;
}
}
}
działa poprawnie, tzn. oblicza mi "a" i wszystko przebiega dobrze, ale wydajność nie jest taka jaką bym chciał, ze względu na umiejscowioną pętlę "for" wewnątrz kernela. Dla dużych M, wątek musi wykonać naprawdę dużo obliczeń, co znacznie spowalnia aplikację i zużywa grafikę tak, że nie da się normalnie pracować. Czy da się to jakoś zooptymalizować? Jak powinien wyglądać kod, żeby to działało pod "dwuwymiarowe bloki" tzn gdy:
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;