Cuda-SDKでnbodyコードを読んだとき、コードのいくつかの行を調べたところ、GPUGems3「FastN-BodySimulationwithCUDA」の論文とは少し異なることがわかりました。
私の質問は次のとおりです。まず、次のコードで記述されているように、blockIdx.xがグローバルからメモリをロードしてメモリを共有することに関与しているのはなぜですか?
for (int tile = blockIdx.y; tile < numTiles + blockIdx.y; tile++)
{
sharedPos[threadIdx.x+blockDim.x*threadIdx.y] =
multithreadBodies ?
positions[WRAP(blockIdx.x + q * tile + threadIdx.y, gridDim.x) * p + threadIdx.x] : //this line
positions[WRAP(blockIdx.x + tile, gridDim.x) * p + threadIdx.x]; //this line
__syncthreads();
// This is the "tile_calculation" function from the GPUG3 article.
acc = gravitation(bodyPos, acc);
__syncthreads();
}
紙によるとこんな感じじゃないですか。なんでだろう
sharedPos[threadIdx.x+blockDim.x*threadIdx.y] =
multithreadBodies ?
positions[WRAP(q * tile + threadIdx.y, gridDim.x) * p + threadIdx.x] :
positions[WRAP(tile, gridDim.x) * p + threadIdx.x];
第二に、ボディごとの複数のスレッドで、なぜthreadIdx.xがまだ関与しているのですか?合計がthreadIdx.yのみによるため、修正値であるか、まったく関与していないと想定されていませんか?
if (multithreadBodies)
{
SX_SUM(threadIdx.x, threadIdx.y).x = acc.x; //this line
SX_SUM(threadIdx.x, threadIdx.y).y = acc.y; //this line
SX_SUM(threadIdx.x, threadIdx.y).z = acc.z; //this line
__syncthreads();
// Save the result in global memory for the integration step
if (threadIdx.y == 0)
{
for (int i = 1; i < blockDim.y; i++)
{
acc.x += SX_SUM(threadIdx.x,i).x; //this line
acc.y += SX_SUM(threadIdx.x,i).y; //this line
acc.z += SX_SUM(threadIdx.x,i).z; //this line
}
}
}
誰かが私にこれを説明できますか?それはより速いコードのためのある種の最適化ですか?