Thursday, March 31, 2011

Mengenal GPU dan CUDA

Beberapa dekade terakhir nama GPU (Graphic Processing Unit) mencuat. GPU pada awalnya dipakai sebagai accelerator untuk pemrosesan grafis pada komputer yang biasanya paling banyak dimanfaatkan oleh aplikasi game. Namun pada perkembangannya, GPU mulai dilirik sebagai accelerator untuk pemrosesan algoritma yang lebih umum, seperti komputasi numerik, realtime medical imaging, komputasi bioinfiormatika, embedded system, dan lainnya. GPU jenis ini dikenal dengan nama GPGPU (General Purpose GPU). Dalam proses desain chip, terutama yang membutuhkan permodelan realtime seperti wireless system, GPU menjadi solusi menarik untuk mengimplementasikan model dalam realtime dan memverifikasinya.

NVIDIA, sebagai sala satu pengembang GPU, melihat potensi ini kemudian mengembangkan seri-seri GPGPU dengan engine yang bisa diakses secara bebas yaitu CUDA. CUDA (Compute Unified Device Architacture) adalah engine untuk mengakses GPU NVIDIA dan API-nya bisa dipanggil oleh program C secara natural. Klaim dari pihak NVIDIA menyatakan bahwa GPU-card NVIDIA Tesla yang mereka miliki bisa memproses operasi foating-point single precision sampai 1TeraFLOPS.


Apa perbedaan CPU dengan GPU? CPU dan GPU saat ini sama-sama memiliki core processor lebih dari satu (multicore). CPU biasanya maksimal saat ini 4-core processor, atau disebut quad-core, sedangkan GPU bisa mencapai sampai 400-core. Walaupun sama-sama multicore, ada perbedaan mendasar pada paradigma multicore-nya. Kalau CPU adalah MIMD, Multiple-Instruction Multiple-Data, sedangkan GPU adalah SIMD, Single-Instruction Multiple-Data.

Instalasi (Driver, CUDA Toolkit, dan SDK)

Berikut langkah-langkah dalam instalasi GPU NVIDIA. Ada tiga macam yang perlu diinstal: NVIDIA Driver, CUDA toolkit, dan SDK (Software Development Kit). Driver, CUDA tookit, dan SDK bisa didownload di website NVIDIA.

Berikut file-file yang saya download untuk Ubuntu 10.0:

NVIDIA-Linux-x86_64-260.19.44.run
cudatoolkit_3.2.16_linux_64_ubuntu10.04.run
gpucomputingsdk_3.2.16_linux.run

Untuk menginstall NVIDIA Driver, matikan dulu X-servernya, jalankan installernya, lalu aktifkan kembali X-servernya atau bisa juga reboot.

(ALT+F1)
$ sudo su
$ /etc/init.d/gdm stop
$ cd <NVIDIA_Driver_Path>
$ ./NVIDIA-Linux-x86_64-260.19.44.run

$ /etc/init.d/gdm start

Untuk menginstall CUDA toolkit, jalankan instaler sebagai root.

$ sudo su
$ ./cudatoolkit_3.2.16_linux_64_ubuntu10.04.run

Disini akan ditanya dimana CUDA akan diinstal, defaultnya diinstall di /usr/local/cuda, tapi bisa juga diset untuk diinstall ditempat lain misalnya /opt/cuda. Setelah installasi selesai, set variable PAT dan LD_LIBRARY_PATH mengarah ke tempat instalasi CUDA. Edit file ~/.bashrc dan tambahkan line berikut (asumsi CUDA diinstall di /usr/local/cuda), lalu eksekusi ~/.bashrc tersebut.

export PATH=$PATH:/usr/local/cuda/bin
export LD_LIBRARY_PATH=/usr/local/cuda/lib

$ source ~/.bashrc

Jika instalasi berhasil, compiler bawaan CUDA (nvcc) sudah bisa dijalankan. Buat  hello world biasa dalam bahasa C,dan coba compile dan jalankan hello worldnya.

$ nvcc –o hello hello.c
$ ./hello
Hello

Compiler CUDA (nvcc) bekerja sama persis dengan gcc, apabila extension filenya adalah .c. Agar code dianggap sebagai CUDA code, ubah extensionya menjadi .cu. Penjelasan lebih lanjut mengenai ini bisa disimak pada bagian “Hello World” dalam artikel ini.

Untuk instalasi SDK, jalankan installer sebagai root.

$ sudo su
$ ./gpucomputingsdk_3.2.16_linux.run

Ketika installasi, lokasi instalasi CUDA toolkit akan diminta. Pada proses intalasi (terutama Ubuntu), akan ditemui beberapa masalah, terutama masalah library. Biasanya ada dua library yang perlu ditambahkan, yaitu library X Windows dan OpenGL (lXi, dan lglut).

$ sudo apt-get install libXi-dev libglut3 libglut3-dev

OK, SDK sudah terinstall dan siap digunakan. Untuk mencobanya, masuk ke directory /C/src, copy project template, compile dan jalankan binary-nya, kalau berhasil, kalimat “Test PASSED” akan muncul.

$ cd /C/src
$ cp –r template coba
$ cd coba
$ make
$ ../../bin/linux/release/template
Test PASSED

Pada beberapa kasus, muncul error linker. Kasus yang sering muncul adalah:
 
/usr/bin/ld: cannot find -lshrutil_x86_64
/usr/bin/ld: cannot find -lcutil_x86_64
/usr/bin/ld: cannot find -lglut
/usr/bin/ld: cannot find -lGL

Berikut solusi-solusinya:

ERROR: /usr/bin/ld: cannot find -lshrutil_x86_64
Cek dulu, seharusnya library -lshrutil_x86_64 ada di /shared/lib, kalau belum ada bisa di-create ulang:

$ cd /shared
$ make


ERROR: /usr/bin/ld: cannot find -lcutil_x86_64
Cek dulu, seharusnya library -lcutil_x86_64 ada di /C/lib, kalau belum ada bisa di-create ulang:

$ cd /C
$ make

ERROR: /usr/bin/ld: cannot find -lglut
ERROR: /usr/bin/ld: cannot find -lGL
Berarti library OpenGL belum tersedia, untuk Ubuntu jalankan command berikut:

$ sudo apt-get install libglut3 libglut3-dev

Lalu tapi ada sedikit tweak untuk Ubuntu, yaitu kalau masih ada error /usr/bin/ld: cannot find -lGL, artinya library /usr/lib/libGL.so broken (lihat http://ubuntuforums.org/showthread.php?t=1480282). Solusinya, delete file /usr/lib/libGL.so, lalu buat link dari /usr/lib/libGL.so.1
 
$ rm /usr/lib/libGL.so
$ ln -s /usr/lib/libGL.so.1 /usr/lib/libGL.so

Sampai disini installasi sudah selesai semua, Driver, CUDA toolkit, dan SDK. Kita bisa coba lagi menjalankan program template.

$ cd /C/src
$ cp –r template coba
$ cd coba
$ make
$ ../../bin/linux/release/template
Test PASSED

CUDA Hello World (First Program)

#include
#include

int main(int argc, char *argv[])
{
    printf("Hello\n");
    return 0;
}

Program hello world dalam C sudah dicoba pada bagian instalasi, dan bisa berjalan dengan baik, karena ketika program hello world tersebut dijalankan, eksekusi hanya dilakukan pada CPU. Kita akan sedikit memodifikasi code hello world sebelumnya, dengan menambahkan dua hal:
  • Fungsi kosong bernama kernel() dengan quaifier __global__
  • Call ke fungsi kosong kernel(), dengan imbuhan <<<1, 1>>>


#include
#include
#include "cuda.h"

__global__ void kernel(void) {
}

int main(int argc, char *argv[])
{
    kernel<<<1,1>>>();
    printf("Hello\n");
    return 0;
}

CUDA menambahkan qualifier __global__ pada standard C. Qualifier ini akan memberitahu compiler bahwa eksekusi fungsi didalam __global__ dilakukan di device (GPU), bukan di host (CPU). Call ke fungsi kernel menggunakan imbuhan <<<1, 1>>> untuk memberitahu, bagaimana fungsi kernel dijalankan di device (GPU). Compile code diatas, dan jalankan programnya, maka akan keluar hasil yang sama, yaitu “Hello”, sama persis dengan sebelum dimodifikasi, karena memang fungsi di GPU kosong. Sekarang kita coba tambahkan fungsi sederhana yang dijalankan di GPU, yaitu fungsi penjumlahan.

#include
#include
#include "cuda.h"

__global__ void add( int a, int b, int *c ) {
    *c = a + b;
}

int main(int argc, char *argv[])
{
    int c;
    int *dev_c;
 
    cudaMalloc( (void**)&dev_c, sizeof(int) );   
    add<<<1,1>>>( 2, 7, dev_c ); 
    cudaMemcpy( &c,  dev_c,  sizeof(int),  cudaMemcpyDeviceToHost );
    printf( "2 + 7 = %d\n", c );
    cudaFree( dev_c );
}

Compile code-nya, lalu jalankan programnya.

$ nvcc -o hello hello.cu
$ ./hello
2 + 7 = 9


Voila! selamat mencoba! (Ya2n)

No comments:

Post a Comment