C ++

Pengaturcaraan GPU dengan C ++

Pengaturcaraan GPU dengan C ++

Gambaran keseluruhan

Dalam panduan ini, kami akan meneroka kehebatan pengaturcaraan GPU dengan C++. Pembangun dapat mengharapkan prestasi yang luar biasa dengan C ++, dan mengakses kekuatan GPU yang luar biasa dengan bahasa tahap rendah dapat menghasilkan beberapa pengiraan terpantas yang ada saat ini.

Keperluan

Walaupun mana-mana mesin yang mampu menjalankan versi Linux moden dapat menyokong penyusun C ++, anda memerlukan GPU berasaskan NVIDIA untuk mengikuti latihan ini. Sekiranya anda tidak mempunyai GPU, anda boleh membuat contoh berkuasa GPU di Amazon Web Services atau penyedia awan lain pilihan anda.

Sekiranya anda memilih mesin fizikal, pastikan anda memasang pemandu proprietari NVIDIA. Anda boleh mendapatkan arahan untuk ini di sini: https: // linuxhint.com / install-nvidia-driver-linux /

Sebagai tambahan kepada pemacu, anda memerlukan kit alat CUDA. Dalam contoh ini, kita akan menggunakan Ubuntu 16.04 LTS, tetapi terdapat muat turun yang tersedia untuk sebilangan besar pengedaran utama di URL berikut: https: // pemaju.nvidia.com / muat turun cuda

Untuk Ubuntu, anda akan memilih .muat turun berasaskan deb. Fail yang dimuat turun tidak akan mempunyai .lanjutan deb secara lalai, jadi saya cadangkan untuk menamakannya menjadi .deb di akhir. Kemudian, anda boleh memasang dengan:

sudo dpkg -i pakej-nama.deb

Anda mungkin akan diminta untuk memasang kunci GPG, dan jika ya, ikuti arahan yang diberikan untuk melakukannya.

Setelah selesai, kemas kini repositori anda:

sudo apt-get kemas kini
sudo apt-get install cuda -y

Setelah selesai, saya cadangkan reboot untuk memastikan semuanya dimuat dengan betul.

Kebaikan Pembangunan GPU

CPU menangani banyak input dan output yang berbeza dan mengandungi sejumlah besar fungsi untuk tidak hanya menangani berbagai macam keperluan program tetapi juga untuk mengatur berbagai konfigurasi perkakasan. Mereka juga menangani memori, caching, bus sistem, segmentasi, dan fungsi IO, menjadikan mereka jack semua perdagangan.

GPU adalah sebaliknya - ia mengandungi banyak pemproses individu yang tertumpu pada fungsi matematik yang sangat sederhana. Oleh kerana itu, mereka memproses tugas berkali-kali lebih cepat daripada CPU. Dengan mengkhususkan diri dalam fungsi skalar (fungsi yang memerlukan satu atau lebih input tetapi hanya menghasilkan satu output), mereka mencapai prestasi yang ekstrem dengan kos pengkhususan yang ekstrem.

Contoh Kod

Dalam kod contoh, kami menambah vektor bersama-sama. Saya telah menambahkan kod versi CPU dan GPU untuk perbandingan kelajuan.
gpu-contoh.cpp kandungan di bawah:

#kemasukan "cuda_runtime.h "
#sertakan
#sertakan
#sertakan
#sertakan
#sertakan
typedef std :: chrono :: high_resolution_clock Jam;
#tentukan ITER 65535
// Versi CPU fungsi tambah vektor
void vektor_add_cpu (int * a, int * b, int * c, int n)
int i;
// Tambahkan elemen vektor a dan b ke vektor c
untuk (i = 0; i < n; ++i)
c [i] = a [i] + b [i];


// Versi GPU fungsi tambah vektor
__global__ void vector_add_gpu (int * gpu_a, int * gpu_b, int * gpu_c, int n)
int i = threadIdx.x;
// Tidak diperlukan gelung kerana masa berjalan CUDA
// akan memuatkan kali ITER ini
gpu_c [i] = gpu_a [i] + gpu_b [i];

int utama ()
int * a, * b, * c;
int * gpu_a, * gpu_b, * gpu_c;
a = (int *) malloc (ITER * sizeof (int));
b = (int *) malloc (ITER * sizeof (int));
c = (int *) malloc (ITER * sizeof (int));
// Kami memerlukan pemboleh ubah yang dapat diakses oleh GPU,
// jadi cudaMallocManaged menyediakan ini
cudaMallocManaged (& gpu_a, ITER * sizeof (int));
cudaMallocManaged (& gpu_b, ITER * sizeof (int));
cudaMallocManaged (& gpu_c, ITER * sizeof (int));
untuk (int i = 0; i < ITER; ++i)
a [i] = i;
b [i] = i;
c [i] = i;

// Panggil fungsi CPU dan waktunya
auto cpu_start = Jam :: sekarang ();
vektor_add_cpu (a, b, c, ITER);
auto cpu_end = Jam :: sekarang ();
std :: cout << "vector_add_cpu: "
<< std::chrono::duration_cast(cpu_end - cpu_start).kira ()
<< " nanoseconds.\n";
// Panggil fungsi GPU dan buat masa
// Braket sudut tiga adalah lanjutan jangka masa CUDA yang membolehkan
// parameter panggilan kernel CUDA yang akan dilalui.
// Dalam contoh ini, kita melewati satu blok utas dengan utas ITER.
auto gpu_start = Jam :: sekarang ();
vector_add_gpu <<<1, ITER>>> (gpu_a, gpu_b, gpu_c, ITER);
cudaDeviceSynchronize ();
auto gpu_end = Jam :: sekarang ();
std :: cout << "vector_add_gpu: "
<< std::chrono::duration_cast(gpu_end - gpu_start).kira ()
<< " nanoseconds.\n";
// Bebaskan peruntukan memori berdasarkan fungsi GPU
cudaFree (a);
cudaFree (b);
cudaFree (c);
// Bebaskan peruntukan memori berdasarkan fungsi CPU
percuma (a);
percuma (b);
percuma (c);
pulangan 0;

Makefile kandungan di bawah:

INC = -I / usr / local / cuda / include
NVCC = / usr / tempatan / cuda / bin / nvcc
NVCC_OPT = -std = c ++ 11
semua:
$ (NVCC) $ (NVCC_OPT) contoh gpu.cpp -o gpu-contoh
bersih:
-rm -f gpu-contoh

Untuk menjalankan contohnya, kumpulkan:

membuat

Kemudian jalankan program:

./ gpu-contoh

Seperti yang anda lihat, versi CPU (vector_add_cpu) berjalan jauh lebih lambat daripada versi GPU (vector_add_gpu).

Sekiranya tidak, anda mungkin perlu menyesuaikan definisi ITER dalam contoh gpu.cu ke bilangan yang lebih tinggi. Ini disebabkan masa penyediaan GPU lebih lama daripada beberapa gelung intensif CPU yang lebih kecil. Saya mendapati 65535 berfungsi dengan baik pada mesin saya, tetapi jarak tempuh anda mungkin berbeza. Namun, setelah anda membersihkan ambang ini, GPU secara dramatik lebih cepat daripada CPU.

Kesimpulannya

Saya harap anda banyak belajar dari pengenalan kami dalam pengaturcaraan GPU dengan C++. Contoh di atas tidak mencapai kejayaan yang besar, tetapi konsep yang ditunjukkan menyediakan kerangka yang boleh anda gunakan untuk menggabungkan idea anda untuk melepaskan kekuatan GPU anda.

Pasang permainan Strategi OpenRA terkini di Ubuntu Linux
OpenRA adalah mesin permainan Strategi Masa Nyata / Bebas yang mencipta semula permainan Westwood awal seperti Command & Conquer klasik: Makluman Mera...
Pasang Dolphin Emulator terkini untuk Gamecube & Wii di Linux
Dolphin Emulator membolehkan anda memainkan permainan Gamecube & Wii pilihan anda di Komputer Peribadi Linux (PC). Menjadi emulator permainan sumber ...
Cara Menggunakan Mesin Cheat GameConqueror di Linux
Artikel ini merangkumi panduan mengenai penggunaan mesin cheat GameConqueror di Linux. Ramai pengguna yang bermain permainan di Windows sering menggun...