BAB V KESIMPULAN DAN SARAN
5.2. Saran Pengembangan
Beberapa saran yang penulis dapat berikan untuk pengembangan skripsi ini adalah sebagai berikut:
1. Meningkatkan jumlah peserta untuk pengujian agar mendapatkan hasil uji beda yang valid.
2. Menambah fasilitas VGA Nvidia CUDA di BB-5 agar praktikum dapat berjalan dengan lancar dan jumlah peserta praktikum dapat ditambah.
3. Membuat aplikasi CUDA dengan menggabungkan beberapa unit PC (Cluster CUDA) dapat dilakukan untuk pengembangan aplikasi Nvidia CUDA. 4. Apabila ingin melakukan uji validalitas dan uji reabilitas sebaiknya dengan
cara membandingkan dua kelompok mahasiswa yang diberi perlakuan berbeda.
DAFTAR PUSTAKA
[1] Benchmark reviews, “ Nvidia GF 100 GPU Fermi Architecture”, diakses dalam
http://benchmarkreviews.com/index.php?option=com_content&task=view&id =518&Itemid=72&limit=1&limitstart=2 pada 22 Agustus 2012.
[2] Farber, Rob, ”CUDA Application Design And Development”, MK, 2011. [3] Guru 3D, “Geforce GTX 680 review”, diakses dalam
http://www.guru3d.com/articles_pages/geforce_gtx_680_review,3.html pada 22 Agustus 2012.
[4] Harvard, “Harvard recognized by NVIDIA as a CUDA Center of Excellence”, dikases dalam
http://www.seas.harvard.edu/news-events/news- archive/2009/harvard-recognized-by-nvidia-as-a-cuda-center-of-excellence-nvidia/?searchterm=None pada 10 April 2012.
[5] Kirk David B., Hwu Wen-mei W., ”Programming Massively Parallel Processors”, MK, 2010.
[6] Mardalis, “Metode Penelitian Suatu Pendekatan Proposal”, PT. Bumi Aksara, Jakarta, 2008.
[7] Nvidia, “NVIDIA CUDA Architecture Introduction & Overview”, Nvidia, 2009.
[8] Nvidia, ”NVIDIA CUDA C Programming Guide version 4”, Nvidia, 2011. [9] Nvidia, ” NVIDIA CUDA C Programming Guide version 4.2”, Nvidia, 2012. [10] Nvidia, ”NVIDIA Fermi Compute Architecture”, Nvidia.
[11] Nvidia, “Tokyo Institute of Technology Selected as Japan’s First CUDA Center of Excellence”, diakses dalam
http://www.nvidia.com/object/io_1270716327243 pada 10 April 2012. [12] Sanders J., Kandrot E., “CUDA By Example”, Addison-Wesley, 2010. [13] Susanto, Stephanus H., “Sistem Operasi Android pada Kuliah Mobile
Programming”, FTEK-UKSW, Salatiga, 2011. (Laporan Tugas Akhir untuk meraih gelar sarjana di FTEK-UKSW).
[14] Tom’s hardware, “Nvidia Powering World’s Most Poweful Supercomputer”, diakses dalam http://www.tomshardware.com/news/Tesla-Titan-Cray-XK6-Supercomputer-Steve-Scott,13669 pada 10 April 2012.
[15] Wikipedia, “CUDA”, diakses dalam http://en.wikipedia.org/wiki/CUDA pada 8 Februari 2012.
[16] Wikipedia, ”GDDR5”, diakses dalam http://en.wikipedia.org/wiki/GDDR5 pada 1 Mei 2012.
[17] Wikipedia, ” Graphics processing unit”, diakses dalam
http://en.wikipedia.org/wiki/Graphics_processing_unit pada 1 Mei 2012.
LAMPIRAN A
PEDOMAN PEMBELAJARAN TOPIK 2 NVIDIA CUDA PROGRAMMING MODEL 1. Tujuan
Melalui pedoman pembelajaran topik 2 diharapkan mahasiswa dapat: • Memahami dan mengerti arsitektur Nvidia CUDA.
• Menguasai dasar-dasar programming model Nvidia CUDA. 2. Materi
2.1. Arsitektur Nvidia CUDA
Nvidia CUDA mempunyai arsitektur berbasis General Purpose Computing Graphics Processing Units (GPGPU). Nvidia CUDA dapat berjalan dengan platform prosesor berbasis x86 dan x64 dari platform manapun dan chipset motherboard yang mendukung PCI-Express Bus. Gambar 1 merupakan gambar arsitektur komputer dengan CUDA.
Gambar 1. Arsitektur komputer dengan CUDA
Pada gambar diatas CUDA dihubungkan melalui interface PCI-Express Bus yang mendukung bandwidth sampai 16 GB/s. PCI-Express dihubungkan oleh Northbridge pada motherboard yang berfungsi menjembatani CPU, DRAM , Southbridge dan PCI-Express.
Nvidia CUDA terdiri dari beberapa komponen yaitu [4, h.2]: 5. Unit pemrosesan di dalam GPU.
6. OS kernel-level yang mendukung inisialisasi dan konfigurasi hardware. 7. User mode driver yang menunjukkan device level API.
8. PTX instruction set architecture (ISA) untuk komputasi paralel kernel dan fungsi.
Saat ini Nvidia CUDA telah mencapai 4 generasi arsitektur. Tabel 1 menunjukkan generasi arsitektur Nvidia CUDA .
Tabel 1. Generasi Arsitektur Nvidia CUDA [2]
Arsitektur Jumlah maksimum SM SP/ CUDA cores Jumlah SP maksimum Shared memory/ cache Maksimum memory bandwidth maksimu m thread per block Dimensi block G80/G92 16 8 128 246 KB shared memory, 512 KB register 86,4 GB/s 512 512 x 512 x 64 GT 200 30 8 240 480KB shared memory, 1920 KB register 141,7 GB/s 512 512x 512 x 64 Fermi 16 32 512 L1 cache 1024 KB, L2 cache 768 KB, 2048 KB register 177,4 GB/s 1024 1024 x 1024 x 64 Kepler 8 192 1536 L1 cache 512 KB, L2 cache 1536 KB, 2048 KB register 192,4 GB/s 1024 1024 x 1024 x 64
GPU pada Nvidia CUDA terdiri beberapa unit Streaming Multiprocessors (SM) seperti yang terlihat pada Gambar 2.
Gambar 2. GPU pada Nvidia CUDA [1]
Setiap generasi arsitektur Nvidia CUDA mempunyai SM yang berbeda-beda. Gambar 3 adalah gambar SM pada arsitektur Fermi.
Gambar 3. SM pada arsitektur Fermi [6, h.8]
Bagian yang terdapat pada setiap SM arsitektur Fermi adalah [6, h.5-8]: • 32 CUDA core yang terdiri dari Arithmetic Logic Unit (ALU) dan
sampai 32 bit precision unit untuk semua instruksi sedangkan FPU mendukung sampai 64 bit.
• 16 unit Load Store unit yang digunakan untuk pengalamatan resource dan destination yang dapat menampung sampai 16 threads per clock. • 4 Special Function Unit (SFU) yang berfungsi mengeksekusi instruksi
transcendental seperti sin,cos dan bilangan kuadrat.
• 2 Warp scheduler untuk penjadwalan 32 thread yang bekerja secara paralel.
• 64 KB Shared memory dan L1 cache.
• Register serbaguna dengan ukuran 32.768 x 32 bit.
2.2. Programming Model Nvidia CUDA
2.2.1. Kernel [5, h.7]
Kernel merupakan fungsi yang dipanggil dari program host dan akan dieksekusi didalam GPU. Sewaktu kernel dipanggil, kernel akan mengeksekusi thread secara paralel. Kernel didefinisikan didalam deklarasi __global__ .
Format penulisan kernel adalah sebagai berikut:
namakernel<<< jumlah block, jumlah threads dalam satu block >>> (Nilai yang dipassingkan);
Contoh pemanggilan fungsi kernel:
1. __global__ void tambah(float* A, float* B, float* C) 2. {
3. int i = threadIdx.x; 4. C[i] = A[i] + B[i]; 5. } 6. int main() 7. { 8. ... 9. tambah<<1, N>>>(A, B, C); 10. ... 11.}
Penjelasan program:
Pertama kali program akan berjalan dari fungsi main pada baris ke 6. Kemudian program akan memanggil fungsi kernel tambah pada baris ke 9. Program akan mengeksekusi kernel pada fungsi dengan deklarasi __global__ pada baris ke 1. Pada baris ke 3 Thread akan disimpan didalam array i dengan tipe integer (1 dimensi). Kemudian pada baris ke 4 vektor A akan ditambah dengan vektor B dan hasilnya akan disimpan dalam vektor C.
2.2.2. Thread [3, h.60]
Thread adalah sekumpulan instruksi yang dapat dijadwalkan. Susunan thread akan mengeksekusi kernel secara bergantian. Setiap thread mempunyai ID yang disebut threadIdx, begitu juga dengan block mempunyai ID yang disebut blockIdx. ThreadIdx dan BlockIdx dapat dinyatakan dalam 3 dimensi vektor yaitu x, y dan z.
Contoh:
ThreadIdx.x , ThreadIdx.y, ThreadIdx.z, BlockIdx.x, BlockIdx.y,BlockIdx.z
2.2.3. Heterogenous Programming [5, h.13]
Pada pemrograman Nvidia CUDA, program dieksekusi di dua device yang terpisah. Prosesor sebagai host berfungsi mengeksekusi program C secara sequential dan GPU sebagai device berfungsi mengeksekusi thread secara paralel. Host dan device juga mempunyai memory masing-masing yang terpisah. Gambar 4 menjelaskan tentang heterogenous programming:
Gambar 4. Heterogeneous programming
Program berjalan dari host code secara serial. Isi dari kode host ini adalah inisialisasi memory dan penyalinan memory dari CPU ke GPU. Setelah itu kernel akan dipanggil dan kode paralel akan dieksekusi didalam device. Satu kernel akan dieksekusi pada satu waktu sehingga hanya ada satu instruksi paralel yang dikerjakan pada satu waktu. Setelah kode paralel selesai dikerjakan oleh device, hasilnya dikembalikan pada host dan apabila masih ada instruksi paralel yang harus dikerjakan maka kernel dapat dipanggil lagi dan dieksekusi didalam device.
2.2.4. Management Memory Nvidia CUDA[3, h.46-50] Management memory Nvidia CUDA :
• CPU dan GPU mempunyai memory yang terpisah • CPU memanajemen GPU memory:
1. Mengalokasi dan membebaskan memory
1.1. cudaMalloc(void ** pointer, size_t nbytes) • memesan lokasi dan kapasitas memory 1.2. cudaMemset(void *pointer, int value, size_t
count)
• mengeset kapasitas dan isi memory 1.3. cudaFree(void * pointer)
• membebaskan memory 2. Menyalin data ke devices
2.1. cudaMemcpy(void *dst, void *src, size_t nbytes, cudaMemcpy direction)
• menyalin memory 2.2. cuda Memcpy direction:
• cudaMemcpyHostToDevice
o menyalin memory dari host ke device
• cudaMemcpyDeviceToHost
o menyalin memory dari device ke host
• cudaMemcpyDeviceToDevice
o menyalin memory dari device ke device
Contoh program manajemen memory pada Nvidia CUDA:
1.__global__ void VecAdd(float* A, float* B, float* C, int N)
2.{
3. int i = blockDim.x * blockIdx.x + threadIdx.x; 4. if (i < N)
5. C[i] = A[i] + B[i]; 6.}
7.int main() 8.{
9. int N = ..;
10. size_t size = N * sizeof(float); 11. float* h_A = (float*)malloc(size); 12. float* h_B = (float*)malloc(size); 13. float* d_A; 14. cudaMalloc(&d_A, size); 15. float* d_B; 16. cudaMalloc(&d_B, size); 17. float* d_C; 18. cudaMalloc(&d_C, size);
19. cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice); 20. cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice); 21. int threadsPerBlock = 256;
22. int blocksPerGrid = (N + threadsPerBlock – 1) / threadsPerBlock;
23. VecAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, N);
24. cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost); 25. cudaFree(d_A);
26. cudaFree(d_B); 27. cudaFree(d_C); 28.}
Penjelasan program:
Program dimulai dari baris ke 7 saat pemanggilan fungsi main. Pada baris ke 10 program memesan memory dengan tipe data float sebanyak N dikali 4 byte kemudian pada baris ke 11 program mengalokasikan vektor A dan B didalam host memory. Baris ke 13 sampai 17 adalah alokasi vektor didalam device memory dengan menggunakan cudaMalloc. Baris ke 19 sampai 20 program menyalin vektor dari host memory ke device memory. Baris ke 21 adalah inisialisasi jumlah thread didalam block sebanyak 256. Baris ke 22 adalah menentukan jumlah block yang dipakai misalnya: N data yang kita pakai adalah
1500 maka jika kita masukkan ke dalam persamaan pada baris ke 22 adalah ( 1500 + 256 – 1) / 256 = 6,85 karena tipe data yang dipakai adalah integer dan
jumlah block yang dipakai adalah bilangan bulat maka jumlah block yang dipakai adalah 6. Karena jumlah block yang dipakai adalah 6 maka total thread yang dapat dipakai adalah 1536 didapat dari perkalian block dengan thread. Selanjutnya pada baris ke 23 adalah pemanggilan kernel VecAdd dan program akan meloncat ke baris nomor 1. Baris ke 3 program akan memberikan ID yang berbeda pada setiap threadId.x, kemudian pada baris ke 4 program akan mengecek ID dari thread. Jika ID dari thread kurang dari N maka thread yang mempunyai ID kurang dari N yang akan mengeksekusi penjumlahan vektor pada baris ke 5. Setelah kernel selesai dieksekusi program akan kembali pada baris ke 24, vektor C akan disalin dari device ke host kemudian baris ke 25 sampai ke 27 adalah membebaskan memory untuk vektor A, B dan C.
3. Ringkasan
1. GPU pada Nvidia CUDA merupakan gabungan dari beberapa Streaming Multiprocessors(SM), SM merupakan gabungan dari beberapa CUDA core. 2. Kernel merupakan fungsi yang dipanggil dari program host dan akan dieksekusi di
dalam GPU.
3. Program pada Nvidia CUDA dieksekusi di 2 devices yang berbeda yaitu CPU dan GPU.
4. Execution model pada Nvidia CUDA menggunakan 2 devices yang terpisah yang mempunyai memory masing-masing, CPU sebagai host mengontrol manajemen memory pada GPU.
4. Soal-Soal Latihan
a) Jelaskan fungsi utama kernel!
b) Apa yang terjadi jika cudaMalloc() tidak dideklarasikan sebelum menyalin memory dari CPU ke GPU?
c) Jelaskan perbedaan kode serial dan kode paralel!
d) Apa yang akan terjadi apabila jumlah thread yang dideklarasikan pada kernel melebihi dari jumlah data yang akan dieksekusi, jelaskan!
e) Jelaskan perbedaan kode device dengan kode host!
5. Daftar pustaka
1. Benchmark reviews, “ Nvidia GF 100 GPU Fermi Architecture”, diakses dalam http://benchmarkreviews.com/index.php?option=com_content&task=view&id=51 8&Itemid=72&limit=1&limitstart=2 pada 22 Agustus 2012.
2. Guru 3D, “Geforce GTX 680 review”, diakses dalam
http://www.guru3d.com/articles_pages/geforce_gtx_680_review,3.html pada 22 Agustus 2012.
3. Kirk David B., Hwu Wen-mei W., ”Programming Massively Parallel Processors”, MK, 2010.
4. Nvidia, “NVIDIA CUDA Architecture Introduction & Overview”, Nvidia, 2009. 5. Nvidia, ” Nvidia CUDA C Programming Guide version 4.2”, Nvidia.2011. 6. Nvidia, ”NVIDIA Fermi Compute Architecture”, Nvidia.
LAMPIRAN B
PEDOMAN PEMBELAJARAN TOPIK 3 NVIDIA CUDA THREADING
1. Tujuan
Melalui pedoman pengajaran topik 3 diharapkan mahasiswa dapat: • Memahami dan mengerti konsep dasar dari thread.
• Menguasai dasar-dasar pemrograman thread. • Mengerti manfaat dari penjadwalan thread.
2. Materi
2.1. Konsep Thread pada Nvidia CUDA
Thread adalah sekumpulan instruksi yang dapat dijadwalkan. Pada setiap Streaming Multiprocessor (SM) GPU Nvidia CUDA, jumlah thread yang dapat ditampung adalah 1536 untuk arsitektur Fermi, sedangkan pada arsitektur G80 dan GT200 jumlah maksimal thread yang dapat ditampung pada setiap SM adalah 768. Thread digunakan untuk mengeksekusi kernel, setiap susunan thread akan mengeksekusi kernel secara bergantian. Thread mempunyai unique ID yang digunakan sebagai alamat dan kontrol, Susunan thread mengeksekusi kernel dapat dilihat pada gambar 1.
Karena jumlah thread yang digunakan untuk eksekusi sangat banyak, maka Nvidia CUDA disebut Single Instruction Multiple Thread (SIMT). SIMT merupakan gabungan dari Single Instruction Multiple Data (SIMD) dan Single Program Multiple Data (SPMD). Tabel 1 menjelaskan definisi dari SIMD dan SPMD.
Tabel 1. Definisi SIMD dan SPMD [2, h.61-62]
Nama Keterangan
Single Instruction Multiple Data (SIMD)
Setiap thread mempunyai kontrol yang sama tetapi dapat menangani banyak data sekaligus
Single Program Multiple Data (SPMD)
Terdapat banyak data yang harus ditangani oleh satu program
Pada Tabel 1 dapat terlihat bahwa konsep dari SIMT yang merupakan gabungan dari SIMD dan SPMD adalah setiap thread akan menjalankan instruksi yang sama tetapi ada banyak data yang bisa ditangani. Hirarki dari thread dapat dilihat pada Gambar 2.
Thread
Block
Grid
Grid merupakan gabungan dari beberapa block
Gambar 2. Hirarki dari Thread [3, h.13]
Thread hanya dapat bekerjasama dengan thread yang ada didalam satu block yang sama. Thread di dalam satu block yang sama dapat berbagi resource dan dapat mengetahui apa yang sedang dikerjakan oleh thread lain di dalam satu block yang sama. Thread dalam CUDA dapat saling sinkronisasi dalam satu block dengan menggunakan fungsi syncthreads(). Tujuan pemanggilan fungsi syncthreads adalah untuk memastikan semua thread dalam block telah menyelesaikan eksekusi sebelum mengerjakan instruksi selanjutnya. Untuk execution model pada thread dapat dilihat pada Gambar 3.
Gambar 3. Execution model [3, h.13]
Gambar 3 menunjukkan execution model pada Nvidia CUDA. o Satu prosesor akan mengeksekusi satu thread.
o Gabungan dari beberapa prosesor (multiprosesor) mengeksekusi satu Block .
2.2.Pemrograman Thread [2, h.8-10]
Setiap thread mempunyai ID yang disebut threadIdx, begitu juga dengan block mempunyai ID yang disebut blockIdx. ThreadIdx dan blockIdx dapat dinyatakan dalam 3 dimensi vektor yaitu x, y dan z.
Contoh:
ThreadIdx.x , ThreadIdx.y, ThreadIdx.z, BlockIdx.x, BlockIdx.y,BlockIdx.z Contoh program:
1. __global__ void tambah(float A[N][N], float B[N][N], float C[N][N])
2. {
3. int i = threadIdx.x; 4. int j = threadIdx.y;
5. C[i][j] = A[i][j] + B[i][j]; 6. } 7. int main() 8. { 9. ... 10. tambah<<1,4,4>>>(A, B, C); 11. ... 12.} Penjelasan program:
Program diatas merupakan modifikasi dari program yang pertama. Perbedaannya adalah menggunakan 2 dimensi vektor untuk eksekusinya yaitu pada baris ke 3 dan baris ke 4. Thread akan disimpan pada array i dan array j, sehingga dapat diilustrasikan seperti pada Gambar 4.
Gambar 4. Block 2 dimensi vektor
Pada baris ke 10 fungsi kernel memanggil 1 block yang berisi 8 thread. Kemudian Program akan mengeksekusi fungsi tambah pada deklarasi __global__ pada baris ke 1. Pada baris ke 3 thread ID vektor x akan disimpan pada array i dan pada baris ke 4 thread ID vektor y akan disimpan pada array j. Kemudian pada baris ke 5 vektor A akan ditambah dengan vektor B secara 2 dimensi dan hasilnya akan disimpan pada vektor C.
Pada gambar diatas program akan mengeksekusi thread pada baris pertama terlebih dahulu baru kemudian setelah thread pada baris pertama selesai, thread pada baris kedua akan dieksekusi.
Thread pada sebuah block dapat juga digabungkan dengan thread pada block lain contohnya ada pada Gambar 5.
Gambar 5. Grid [3, h.39]
Terdapat sebuah grid yang memiliki 3 block didalamnya masing-masing block mempunyai 5 buah thread Yang mempunyai thread ID 0, 1, 2, 3 dan 4 apabila semua thread ingin digabungkan untuk mengeksekusi kernel maka caranya adalah dengan instruksi sebagai berikut:
blockIdx.x *blockDim.x + threadIdx.x
misal:
blockIdx.x (0) * blockDim.x (5) + threadIdx.x (0) = 0 blockIdx.x (0) * blockDim.x (5) + threadIdx.x (1) = 1 blockIdx.x (1) * blockDim.x (5) + threadIdx.x (0) = 5 blockIdx.x (2) * blockDim.x (5) + threadIdx.x (4) = 14
blockidx.x adalah ID dari block.
blockDim.x adalah banyaknya thread di dalam block. threadIdx.x adalah ID dari thread.
Maka thread ID nya menjadi adalah 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Maka terdapat 15 thread dengan thread ID yang berbeda-beda.
2.3. Penjadwalan Thread [1, h.71-74]
Penjadwalan thread adalah bagian yang penting dan harus diperhatikan dalam pemrograman Nvidia CUDA . Penjadwalan thread dalam Nvidia CUDA disebut dengan warp. Pada setiap warp berisi 32 unit thread yang hanya bisa dijadwalkan didalam 1 Streaming Multiprocessor (SM).
Semisal terdapat 256 thread didalam sebuah block maka jumlah warp yang bisa dijadwalkan yaitu 256/32 = 8 warp. Jika pada setiap SM terdapat 3 block maka jumlah warp menjadi 8 *3 = 24 warp yang bisa dijadwalkan. Pada arsitektur Fermi maksimal thread pada setiap SM adalah 1024 maka jumlah warp yang bisa dijadwalkan adalah 1024/32 = 32 warp pada setiap SM arsitektur Fermi. Contoh penjadwalan warp dapat dilihat pada gambar 6.
Gambar 6. Penjadwalan Warp [4, h.10]
Gambar 6 merupakan gambar penjadwalan warp. Pada penjadwalan pertama thread block 1 melakukan eksekusi tetapi intruksi nomor 7 memerlukan waktu yang lama untuk menunggu hasil dari instruksi sebelumnya kemudian thread block 1 akan masuk dalam waiting mode. Kemudian thread block 2 warp 1 akan memulai mengerjakan instruksi tetapi karena instruksi nomor 3 membutuhkan waktu yang lama maka thread block 3 akan mengambil alih. Setelah instruksi nomor 1 dan 2 selesai namun instruksi nomor 3 thread block 2 belum selesai. Maka thread block 3 kembali mengerjakan instruksi pada warp 2 namun kembali intruksi nomor 3 pada thread block 3 memerlukan waktu untuk menunggu hasil maka thread block 2 mengambil alih karena instruksi nomor 3 siap dikerjakan.
Setelah thread block 2 selesai mengerjakan, thread block 1 mengambil alih karena instruksi nomor 7 siap untuk dieksekusi. Setelah thread block 1 selesai maka kembali melakukan penjadwalan lagi pada thread block 1 tetapi dengan instruksi yang berbeda, setelah selesai thread block 3 kembali mengambil alih untuk mengerjakan instruksi nomor 3 dan 4. Dengan penjadwalan warp yang cukup maka hardware akan bekerja maksimal karena hardware akan selalu mengeksekusi intruksi sehingga selalu tetap sibuk.
2.4. Transparent Scalability [1, h.68-69]
Kemampuan untuk menyelesaikan suatu aplikasi dengan perbedaan kecepatan dalam eksekusinya disebut dengan transparent scalability. Setiap block dapat dieksekusi dalam urutan apapun tergantung dari susunan block. Transparent scalability ditunjukkan oleh Gambar 7.
Gambar 7. Transparent scalability
Pada gambar diatas block yang akan dieksekusi pertama merupakan block pada baris pertama terlebih dahulu. Device sebelah kanan akan lebih cepat mengeksekusi karena dapat mengeksekusi 4 block sekaligus sedangkan pada
device sebelah kiri akan lebih lama karena block yang dieksekusi hanya 2 block pada satu waktu.
3. Ringkasan
a) Thread berfungsi untuk mengeksekusi kernel.
b) Nvidia CUDA menggunakan SIMT yang merupakan gabungan dari SIMD dan SPMD.
c) Gabungan dari beberapa thread membentuk block, gabungan dari beberapa block membentuk grid.
d) Thread dapat dinyatakan dalam 3 dimensi vektor. e) Warp digunakan untuk menjadwalkan thread.
f) Transparent scalability adalah kemampuan untuk menyelesaikan suatu aplikasi dengan perbedaan kecepatan dalam eksekusinya.
4. Soal - Soal Latihan
a) Jelaskan mengapa Nvidia CUDA bisa disebut SIMT!
b) Terdapat 7 SM pada Nvidia GTX 460 (Fermi) setiap SM mempunyai 48 core hitunglah berapa jumlah warp yang bisa dijadwalkan!
c) Analisalah program dibawah ini !
• Gambarlah bentuk block dan thread dari program diatas! • Apa isi dari int C pada program diatas?
• Manakah konfigurasi block yang lebih cepat kernel<<2,4,4>> atau kernel<<1,16>>??
1. __global__ void kernel(int a[n][n], int b[n][n], int c[n][n])
2. {
3. int i = blockIdx.x *blockDim.x + threadIdx.x 4. int j = blockIdx.y *blockDim.y+ threadIdx.y 5. if (i < N && j < N)
6. C[i][j] = A[i][j] + B[i][j]; 7. } 8. int main() 9. { 10. N= 1000; 11. ... 12. kernel<<1,2,8>>>(A, B, C); 13. ... 14.}
5. Daftar Pustaka
1. Kirk David B., Hwu Wen-mei W., ”Programming Massively Parallel Processors”, MK, 2010.
2. Nvidia, ”Nvidia CUDA C Programming Guide version 4”, Nvidia, 2011. 3. Nvidia, “Getting Started With CUDA, “Nvidia, 2008.
LAMPIRAN C
PEDOMAN PRAKTIKUM TOPIK 1 NVIDIA CUDA BASIC 1. Tujuan
Melalui pedoman praktikum topik 1 diharapkan mahasiswa menguasai konsep: • Pembuatan program Nvidia CUDA sederhana.
• Penyalinan memory, eksekusi kernel dan menampilkan hasil eksekusi program Nvidia CUDA sederhana.
• Eksekusi thread pada kernel.
2. Dasar teori
Nvidia CUDA merupakan mesin pemrosesan paralel yang menggunakan CPU dan GPU untuk melakukan eksekusi program secara paralel. Nvidia CUDA menggunakan CPU untuk mengeksekusi kode host secara sequential dan GPU untuk mengeksekusi kode device secara paralel. Gambar 1 menunjukkan diagram alir eksekusi Nvidia CUDA.
Penjelasannya adalah sebagai berikut [5]:
5. Alur kerja yang pertama yaitu CPU akan menyalin semua data yang dibutuhkan GPU untuk eksekusi dari main memory ke GPU memory onboard.
6. Setelah semua data yang dibutuhkan GPU untuk proses eksekusi disalin. CPU akan mengerjakan kode sequential dan kemudian akan memberikan instruksi yang akan dikerjakan oleh GPU.
7. GPU akan mengeksekusi secara paralel.
8. Hasil dari pemrosesan paralel akan disalin ke main memory.
2.1. Kernel [2, h.42]
Kernel merupakan fungsi yang dipanggil dari program host dan dieksekusi didalam GPU.
Format pemanggilan kernel:
Namakernel <<< jumlah block, jumlah threads dalam satu block >>> (Nilai yang dipassingkan);
2.2. Thread [2, h.60]
Thread adalah sekumpulan instruksi yang dapat dijadwalkan. Gabungan dari thread disebut dengan block, gabungan dari beberapa block disebut dengan grid. Susunan thread akan mengeksekusi kernel secara bergantian. Thread mempunyai ID yang digunakan sebagai alamat dan kontrol, ilustrasi dapat dilihat pada Gambar 2.
. Gambar 2. Susunan Thread mengeksekusi Kernel [3, h.5]
2.3. CUDA Template
CUDA template adalah kode minimum yang digunakan untuk mengeksekusi GPU. CUDA template terdiri dari kode host dan kode device. Potongan kode di bawah adalah kode template untuk aplikasi sederhana:
1. #include <stdio.h> 2. #include <cuda.h>
3. __global__ void square_array(float * a, int N)
4. { 5. <Kode GPU> 6. } <Kode CPU> 7. int main(void) 8. {
9. //Inisialisasi memory CPU
10. float *a_h, *a_d; 11. const int N = 10;
12. size_t size = N * sizeof(float); 13. a_h = (float *)malloc(size);
14. //Inisialisasi memory GPU
15. cudaMalloc((void **) &a_d, size);
16. //Penyalinan data dari CPU ke GPU
17. cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);
18. //pemanggilan kernel
19. kernel<<< jumlah block, jumlah thread >>> (a_d, N);
20. //Penyalinan data dari GPU ke CPU