![]() |
ノート/CUDA/CUDA5.5+Fedora19https://pepper.is.sci.toho-u.ac.jp:443/pepper/index.php?%A5%CE%A1%BC%A5%C8%2FCUDA%2FCUDA5.5%2BFedora19 |
![]() |
ノート
訪問者 8917 最終更新 2013-08-20 (火) 16:28:36
旧バージョン ノート/CUDA/CUDA設定onFedora12
Centos6.4はまだマザーボードのチップセットに対応していなかったので、Fedora 19にする。
/etc/default/grub の中で、GRUB_CMDLINE_LINUX= の末尾にmodeset=0を追加して grub2-mkconfig -o /boot/grub2/grub.cfg 再起動 yum install gcc kernel-devel init 3 <<< Xサーバーを止めるのに必須(XWinに戻すにはinit 5) 持ってきたドライバ NVIDIA....run を実行 ファイルモードを755にして ....run -Z
rpm -i cuda-repo-fedora18-5.5.0....rpm
yum install cuda <<< これはやらないほうが良いらしい
yum install lsb
システムレベルのインストールだと、/usr/local/cuda-5.5の下に開発環境(samples)を展開し、一般ユーザにとってはread-onlyになってしまう。
一般ユーザが開発できるためには、コマンド
cuda-install-samples-5.5.sh ./ (但し「./」はインストールしたい場所)
を実行する。そうすると
Copying samples to .//NVIDIA_CUDA-5.5_Samples now... Finished copying samples.
で、今いる下「./」に NVIDIA_CUDA-5.5_Samples というディレクトリを作って、その中にサンプルファイルが(書き込み可能で)コピーされる。 ここを使って、プログラムを作ればよい。
以下の話は、/usr/local/cuda-5.5においた(システム用の)開発ディレクトリ上で実験している。一般ユーザは、自分のディレクトリの下に展開したNVIDIA_CUDA-5.5_Samplesの下であると読み替えてほしい。
cd /usr/local/cuda-5.5/samples makeこれでmakeが終わると、バイナリは/usr/local/cuda-5.5/samples/bin/x86_64/linux/releaseにできるので
cd /usr/local/cuda-5.5/samples/bin/x86_64/linux/release
./deviceQuery ./deviceQuery Starting... CUDA Device Query (Runtime API) version (CUDART static linking) Detected 1 CUDA Capable device(s) Device 0: "GeForce GTX TITAN" CUDA Driver Version / Runtime Version 5.5 / 5.5 CUDA Capability Major/Minor version number: 3.5 Total amount of global memory: 6143 MBytes (6441730048 bytes) (14) Multiprocessors x (192) CUDA Cores/MP: 2688 CUDA Cores GPU Clock rate: 876 MHz (0.88 GHz) Memory Clock rate: 3004 Mhz Memory Bus Width: 384-bit L2 Cache Size: 1572864 bytes Max Texture Dimension Size (x,y,z) 1D=(65536), 2D=(65536,65536), 3D=(4096,4096,4096) Max Layered Texture Size (dim) x layers 1D=(16384) x 2048, 2D=(16384,16384) x 2048 Total amount of constant memory: 65536 bytes Total amount of shared memory per block: 49152 bytes Total number of registers available per block: 65536 Warp size: 32 Maximum number of threads per multiprocessor: 2048 Maximum number of threads per block: 1024 Maximum sizes of each dimension of a block: 1024 x 1024 x 64 Maximum sizes of each dimension of a grid: 2147483647 x 65535 x 65535 Maximum memory pitch: 2147483647 bytes Texture alignment: 512 bytes Concurrent copy and kernel execution: Yes with 1 copy engine(s) Run time limit on kernels: Yes Integrated GPU sharing Host Memory: No Support host page-locked memory mapping: Yes Alignment requirement for Surfaces: Yes Device has ECC support: Disabled Device supports Unified Addressing (UVA): Yes Device PCI Bus ID / PCI location ID: 1 / 0 Compute Mode: < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) > deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 5.5, CUDA Runtime Version = 5.5, NumDevs = 1, Device0 = GeForce GTX TITAN Result = PASSとなった。
// CUDA runtime #include <cuda_runtime.h> // helper functions and utilities to work with CUDA #include <helper_functions.h> #include <helper_cuda.h>を追加
CUT_DEVICE_INIT(argc, argv);がなくなって、代わりに
int devID = findCudaDevice(argc, (const char **)argv);を使うらしい。
StopWatchInterface *timer = 0; sdkCreateTimer(&timer); sdkStartTimer(&timer); 何かする sdkStopTimer(&timer); printf("計算時間 =%f(ms)\n", sdkGetTimerValue(&timer)); sdkDeleteTimer(&timer);としている。
cudaEvent_t start, stop; float time; cudaEventCreate(&start); cudaEventCreate(&stop); cudaEventRecord( start, 0 ); kernel<<<grid,threads>>> ( d_odata, d_idata, size_x, size_y, NUM_REPS); cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time, start, stop ); cudaEventDestroy( start ); cudaEventDestroy( stop );Here cudaEventRecord() is used to place the start and stop events into the default stream, stream 0. The device will record a timestamp for the event when it reaches that event in the stream. The cudaEventElapsedTime() function returns the time elapsed between the recording of the start and stop events. This value is expressed in milliseconds and has a resolution of approximately half a microsecond. Like the other calls in this listing, their specific operation, parameters, and return values are described in the CUDA Toolkit Reference Manual. Note that the timings are measured on the GPU clock, so the timing resolution is operating-system-independent.
あとはほとんどそのままで動いた。変更後のプログラムは
#include <stdio.h> //include <cutil.h> Disappeared // CUDA runtime #include <cuda_runtime.h> // helper functions and utilities to work with CUDA #include <helper_functions.h> #include <helper_cuda.h> //#define FLOAT float #define FLOAT double #define BLOCK 2048 /* Number of blocks */ #define THREAD 32 /* Number of threads per block */ #define STRIPS 65536*256 /* Number of total strips */ //#define STRIPS 65536 /* Number of total strips */ void Host(FLOAT *Result); __global__ void Kernel(FLOAT *Result); FLOAT h_result[THREAD*BLOCK]; int main(int argc, char** argv){ StopWatchInterface *timer = 0; sdkCreateTimer(&timer); //unsigned int timer; FLOAT pi; //CUT_DEVICE_INIT(argc, argv); int devID = findCudaDevice(argc, (const char **)argv); FLOAT *d_result; cudaMalloc((void**) &d_result, sizeof(FLOAT)*THREAD*BLOCK); cudaMemset(d_result, 0, sizeof(FLOAT)*THREAD*BLOCK); sdkStartTimer(&timer); cudaMemcpy(d_result, h_result, sizeof(FLOAT)*THREAD*BLOCK, cudaMemcpyHostToDevice); fprintf(stderr, "THREAD=%d, BLOCK=%d\n", THREAD, BLOCK); dim3 grid(BLOCK, 1, 1); dim3 threads(THREAD, 1, 1); Kernel<<< grid, threads >>>(d_result); cudaMemcpy(h_result, d_result, sizeof(FLOAT)*THREAD*BLOCK, cudaMemcpyDeviceToHost); sdkStopTimer(&timer); printf("計算時間 =%f(ms)\n", sdkGetTimerValue(&timer)); sdkDeleteTimer(&timer); pi=0.0; for (int k=0; k<THREAD*BLOCK; k++) { pi += h_result[k]; //printf("Result[%d]=%15.12f\n", k, h_result[k]); } printf("GPU計算結果 =%15.12f\n", (pi - (((FLOAT)0.5)/((FLOAT)STRIPS))) * (FLOAT)4.0); cudaFree(d_result); sdkCreateTimer(&timer); sdkStartTimer(&timer); Host(h_result); sdkStopTimer(&timer); printf("ホストの計算時間 =%f(ms)\n", sdkGetTimerValue(&timer)); sdkDeleteTimer(&timer); pi=0.0; for (int k=0; k<THREAD*BLOCK; k++) { pi += h_result[k]; //printf("Result[%d]=%15.12f\n", k, h_result[k]); } printf("host計算結果 =%15.12f\n", (pi - (((FLOAT)0.5)/((FLOAT)STRIPS))) * (FLOAT)4.0); //getch(); } __global__ void Kernel(FLOAT *Result) { //GPUでの処理 int ix=blockIdx.x*blockDim.x + threadIdx.x; FLOAT tmp=0.0; for(int k=0; k<(STRIPS/BLOCK/THREAD); k++){ FLOAT x = ((FLOAT) ((ix*(STRIPS/BLOCK/THREAD))+k)) / ((FLOAT)STRIPS); tmp+=((FLOAT)sqrt(1.0-x*x)) / ((FLOAT)STRIPS); } Result[ix]=tmp; } void Host(FLOAT *Result){ //ホスト側での計算 int k, ix; FLOAT x, tmp; for(ix=0; ix<(THREAD*BLOCK); ix++){ tmp = 0.0; for(k=0; k<(STRIPS/BLOCK/THREAD); k++){ x = ( (((FLOAT)ix)*((FLOAT)(STRIPS/BLOCK/THREAD))) + (FLOAT)k) / ((FLOAT)STRIPS); tmp=tmp+(((FLOAT)sqrt(1-(x*x))) / ((FLOAT)STRIPS) ); //printf("xi=%15.12f\n", ((FLOAT)sqrt(1.0-x*x)) / ((FLOAT)STRIPS)); } Result[ix]=tmp; } }
実行結果は
GPU Device 0: "GeForce GTX TITAN" with compute capability 3.5 THREAD=32, BLOCK=2048 計算時間 =3.423000(ms) GPU計算結果 = 3.141592653573 ホストの計算時間 =359.904999(ms) host計算結果 = 3.141592653573
となった。
titanでは/usr/local/cuda/bin/の下に、プロファイラが2つ入っている。