CUDA カーネルで printf を使用して観察した動作がわかりません。誰かがこれに光を当てることができますか? これが正常な場合、それはなぜですか?カーネル内で変更 (デバッグ) される前にデータを確実に印刷する方法はありますか?
コードは次のとおりです。
~>more *
::::::::::::::
Makefile
::::::::::::::
all:
nvcc -o WTF.cu.o -arch=sm_21 -c WTF.cu
g++ -o WTF.exe -I/usr/local/cuda/include WTF.cpp WTF.cu.o -L/usr/local/cuda/lib64 -lcuda -lcudart
::::::::::::::
WTF.cpp
::::::::::::::
#include <iostream> // cout
#include <cstdlib> // rand, srand
#include <cuda_runtime_api.h> // cudaXXX
void PrintOnGPU ( unsigned int const iDataSize, int * const iopData );
using namespace std;
int main ()
{
// Allocate and initialize CPU data
unsigned int dataSize = 4;
srand ( time ( NULL ) ); // Random seed
int * pCPUData = ( int * ) malloc ( sizeof ( int ) * dataSize );
for ( unsigned int i = 0; i < dataSize; i++ ) { pCPUData[i] = rand () % 100; cout << "CPU : " << pCPUData[i] << endl; }
// Print from GPU
int * pGPUData = NULL;
cudaMalloc ( ( void ** ) &pGPUData, dataSize * sizeof ( int ) );
cudaMemcpy ( pGPUData, pCPUData, dataSize * sizeof ( int ), cudaMemcpyHostToDevice );
PrintOnGPU ( dataSize, pGPUData );
// Get out
cudaFree ( pGPUData );
if ( pCPUData ) { free ( pCPUData ); pCPUData = NULL; }
return 0;
}
::::::::::::::
WTF.cu
::::::::::::::
#include "stdio.h"
__global__ void WTF ( unsigned int const iDataSize, int * const iopData )
{
if ( iDataSize == 0 || !iopData ) return;
// Don't modify : just print
unsigned long long int tIdx = blockIdx.x * blockDim.x + threadIdx.x; // 1D grid
if ( tIdx == 0 )
{
for ( unsigned int i = 0; i < iDataSize; i++ )
printf ( "GPU : %i \n", iopData[i] );
}
__syncthreads();
// Modify
// iopData[tIdx] = 666; // WTF ?...
}
void PrintOnGPU ( unsigned int const iDataSize, int * const iopData )
{
WTF<<<2,2>>> ( iDataSize, iopData );
}
そして、予想通り、100 を超える値は得られません (cpp ファイルの 15 行目: rand () % 100):
~>make; ./WTF.exe
nvcc -o WTF.cu.o -arch=sm_21 -c WTF.cu
g++ -o WTF.exe -I/usr/local/cuda/include WTF.cpp WTF.cu.o -L/usr/local/cuda/lib64 -lcuda -lcudart
CPU : 38
CPU : 73
CPU : 28
CPU : 82
GPU : 38
GPU : 73
GPU : 28
GPU : 82
ここで、cu ファイル (iopData[tIdx] = 666) の 17 行目のコメントを外します。すべての値を 666 (つまり 100 以上) に変更します。CUDA カーネルでデータを変更する前に、4 つのデータ (cpp ファイルで dataSize = 4)、2 X 2 グリッド、および __syncthreads () があるため、変更されたデータを決して印刷しないでください。ただし、これを取得します(変更されたデータを値666で印刷):
~>make; ./WTF.exe
nvcc -o WTF.cu.o -arch=sm_21 -c WTF.cu
g++ -o WTF.exe -I/usr/local/cuda/include WTF.cpp WTF.cu.o -L/usr/local/cuda/lib64 -lcuda -lcudart
CPU : 29
CPU : 72
CPU : 66
CPU : 90
GPU : 29
GPU : 72
GPU : 666
GPU : 666
これらの 666 が表示される理由がわかりません。この動作が正常である場合、それはなぜですか?
FH