このソース コードでは、4 つのスレッドもあり、カーネル関数は 10 個の配列すべてにアクセスできます。どのように?
#define N 10 //(33*1024)
__global__ void add(int *c){
int tid = threadIdx.x + blockIdx.x * gridDim.x;
if(tid < N)
c[tid] = 1;
while( tid < N)
{
c[tid] = 1;
tid += blockDim.x * gridDim.x;
}
}
int main(void)
{
int c[N];
int *dev_c;
cudaMalloc( (void**)&dev_c, N*sizeof(int) );
for(int i=0; i<N; ++i)
{
c[i] = -1;
}
cudaMemcpy(dev_c, c, N*sizeof(int), cudaMemcpyHostToDevice);
add<<< 2, 2>>>(dev_c);
cudaMemcpy(c, dev_c, N*sizeof(int), cudaMemcpyDeviceToHost );
for(int i=0; i< N; ++i)
{
printf("c[%d] = %d \n" ,i, c[i] );
}
cudaFree( dev_c );
}
10 スレッドを作成しない理由 例) add<<<2,5>>> or add<5,2>>>
N が 10 より大きい場合、合理的に少数のスレッドを作成する必要があるため 例) 33*1024.
このソース コードは、このケースの例です。配列は 10、cuda スレッドは 4 です。4 つのスレッドだけで 10 個の配列すべてにアクセスする方法。
cudaの詳細で、threadIdx、blockIdx、blockDim、gridDimの意味についてのページを参照してください。
このソースコードでは、
gridDim.x : 2 this means number of block of x
gridDim.y : 1 this means number of block of y
blockDim.x : 2 this means number of thread of x in a block
blockDim.y : 1 this means number of thread of y in a block
2*2(ブロック * スレッド) であるため、スレッドの数は 4 です。
カーネル関数の追加では、スレッドの 0、1、2、3 インデックスにアクセスできます
->tid = threadIdx.x + blockIdx.x * blockDim.x
①0+0*2=0
②1+0*2=1
③0+1*2=2
④1+1*2=3
index 4, 5, 6, 7, 8, 9 の残りにアクセスする方法。 while ループ内に計算があります。
tid += blockDim.x + gridDim.x in while
** カーネルの最初の呼び出し **
-1 ループ: 0+2*2=4
-2 ループ: 4+2*2=8
-3 ループ: 8+2*2=12 (ただし、この値は false です。out 中!)
** カーネルの 2 回目の呼び出し **
-1 ループ: 1+2*2=5
-2 ループ: 5+2*2=9
-3 ループ: 9+2*2=13 (ただし、この値は偽です。アウト中です!)
** カーネルの 3 回目の呼び出し **
-1 ループ: 2+2*2=6
-2 ループ: 6+2*2=10 (ただし、この値は false です。out 中!)
** カーネルの 4 回目の呼び出し **
-1 ループ: 3+2*2=7
-2 ループ: 7+2*2=11 (ただし、この値は false です。out 中!)
したがって、0、1、2、3、4、5、6、7、8、9 のすべてのインデックスが tid 値でアクセスできます。
このページを参照してください。
http://study.marearts.com/2015/03/to-process-all-arrays-by-reasonably.html
評判が悪くてアップロードできません。