Dalam pemrograman perangkat lunak, mungkinkah CPU dan GPU memuat 100%?


43

Ini adalah pertanyaan umum tentang topik yang menurut saya menarik sebagai gamer: kemacetan dan pemrograman CPU / GPU. Jika saya tidak salah, saya menjadi mengerti bahwa CPU dan GPU menghitung barang, tetapi yang satu lebih baik dalam beberapa perhitungan daripada yang lain karena perbedaan dalam arsitektur. Misalnya, cracking hashes atau cryptocurrency mining tampaknya jauh lebih efisien pada GPU daripada pada CPU.

Jadi saya bertanya-tanya: apakah memiliki GPU pada 100% beban sementara CPU pada 50% (misalnya) tidak bisa dihindari?

Atau, lebih tepatnya: Dapatkah beberapa perhitungan yang biasanya dilakukan oleh GPU dilakukan oleh CPU jika yang pertama adalah pada beban 100%, sehingga keduanya mencapai beban 100%?

Saya sudah mencari sedikit tentang subjek, tetapi kembali dengan tangan kosong. Saya pikir dan berharap ini ada di tempatnya dalam ayat ini dan terbuka untuk dokumentasi atau kuliah yang mungkin Anda berikan kepada saya!


53
Sepele mungkin untuk memiliki CPU dan GPU keduanya menjalankan loop tak terbatas NO-OPpada saat yang sama, yang akan menyebabkan keduanya memiliki beban 100%.
Jörg W Mittag

17
Mengikuti titik @ Jörg, satu-satunya hal yang diukur oleh CPU% adalah seberapa kecil waktu yang dihabiskan untuk menunggu prosesor lain. 100% bisa menjadi hal yang baik jika programnya efisien, atau hal yang buruk jika programnya tidak efisien. Terlalu banyak waktu, orang-orang fokus pada CPU% seolah-olah itu adalah ukuran kinerja - bukan.
Mike Dunlavey

22
Crysis asli melakukan ini dengan baik.
CubicleSoft

5
@ MikeDunlavey Anda membawa poin yang bagus. Dengan mobil kami tidak mengukur kinerja mereka dengan RPM, kami mengukur kecepatan.
Kapten Man

1
@ JörgWMittag: CPU, mungkin. Tetapi OS dan GPU telah menghentikan pemecah masalah untuk menangani loop tak terbatas. Yaitu, jika shader tidak lengkap dalam jumlah waktu yang wajar, shader akan mati dan GPU diatur ulang.
Nicol Bolas

Jawaban:


62

Secara teoritis ya, tetapi secara praktis jarang.

Baik CPU dan GPU sudah selesai-turing , jadi algoritma apa pun yang dapat dihitung oleh satu juga dapat dihitung oleh yang lain. Pertanyaannya adalah seberapa cepat dan nyaman.

Sementara GPU unggul dalam melakukan perhitungan sederhana yang sama pada banyak titik data dari dataset besar, CPU lebih baik pada algoritma yang lebih kompleks dengan banyak percabangan. Pada sebagian besar masalah, perbedaan kinerja antara implementasi CPU dan GPU sangat besar. Itu berarti menggunakan satu untuk mengambil pekerjaan dari yang lain ketika macet tidak akan benar-benar mengarah pada peningkatan kinerja.

Namun, harga yang harus Anda bayar untuk ini adalah bahwa Anda harus memprogram semuanya dua kali, sekali untuk CPU dan sekali untuk GPU. Itu lebih dari dua kali lebih banyak bekerja karena Anda juga harus menerapkan logika switching dan sinkronisasi. Logika itu sangat sulit untuk diuji, karena perilakunya tergantung pada beban saat ini. Harapkan sangat tidak jelas dan tidak mungkin mereproduksi bug dari aksi ini.


1
Anda menyebutkan bahwa Dengan sebagian besar masalah, perbedaan kinerja antara implementasi CPU dan GPU sangat besar , saya sebenarnya cukup tertarik sejauh mana kesenjangan kinerja. Apakah Anda memiliki angka atau artikel tentang ini (misalnya, pada contoh rendering tekstur 3D)? Terima kasih atas jawaban dan waktu Anda!
MadWard

2
Anda mungkin ingin menambahkan bahwa ada biaya kinerja untuk sinkronisasi antara CPU dan GPU, jadi Anda umumnya ingin meminimalkan jumlah transfer antara keduanya. Juga, menambahkan secara naif cabang-cabang untuk "jangan mengeksekusi pada elemen-elemen yang sudah dikerjakan CPU" tidak akan membelikan Anda apa-apa, karena utas GPU beroperasi di depan.
Ethan

3
@gardenhead Tidak ada di alam semesta yang mendukung rekursi tak terbatas, karena alam semesta adalah ukuran terbatas dan memiliki kepadatan informasi terbatas. "Turing-kelengkapan" suatu sistem umumnya merupakan diskusi tentang apa yang mungkin dilakukan dengan menghilangkan kendala tersebut.
Random832

3
Saya memiliki sedikit keraguan bahwa GPU modern secara teknis setidaknya sedekat Turing kelengkapan seperti PC 80-an ... namun, jika Anda mencoba menjalankan algoritma umum pada GPU biasanya akan berubah menjadi prosesor berurutan yang juga tidak akan lebih cepat dari PC 80-an, sehingga Turing-kelengkapan GPU dalam praktiknya hampir tidak lebih berguna daripada Turing-kelengkapan Brainfuck .
leftaroundabout

7
@leftaroundabout GPU modern sepele Turing lengkap seperti CPU apa pun . Kelengkapan Turing tidak ada hubungannya dengan: 1) kinerja 2) keterbacaan sumber. CPU 80-an sedekat TC dengan yang lainnya: baik TC atau bukan (opsi terakhir tidak masuk akal).
Margaret Bloom

36

Itu tidak terkait dengan pemrograman game. Beberapa kode ilmiah juga dapat menggunakan GPU dan CPU.

Dengan pemrograman hati-hati dan menyakitkan, misalnya dengan menggunakan OpenCL atau CUDA , Anda dapat memuat GPU dan CPU Anda mendekati 100%. Sangat mungkin Anda harus menulis potongan kode berbeda untuk GPU (disebut kode "kernel") dan untuk CPU, dan beberapa kode lem yang membosankan (terutama untuk mengirim ke GPU kode kode yang dikompilasi).

Namun, kodenya akan rumit, dan Anda mungkin perlu menyetelnya ke perangkat keras tertentu yang Anda jalankan, khususnya karena transmisi data antara GPU & CPU mahal.

Baca lebih lanjut tentang komputasi heterogen .

Lihat juga OpenACC , didukung oleh versi GCC terbaru (mis. GCC 6 pada Juni 2016)


1
Anda benar, tag dan judul saya menyesatkan, menghapus game, dan menambahkan kinerja / optimisasi. Saya tidak bermaksud bahwa itu eksklusif untuk permainan, tetapi di situlah saya menyadarinya. Saya pikir itu juga harus sangat spesifik untuk perangkat keras. Terima kasih atas jawaban dan tautan Anda!
MadWard

3
Ini akan cukup banyak berakhir dengan dua algoritma. Saya mencobanya sekali: seluruh gambar sekaligus untuk GPU, dan banyak gambar sekaligus untuk CPU (untuk penyalahgunaan cache besar). Memang menyakitkan, terutama untuk mempertahankan.
PTwr

11

Dari sudut pandang superkomputer, lebih baik tidak berpikir dalam beban CPU / GPU dalam persentase tetapi menentukan berapa banyak operasi yang dibutuhkan oleh masalah Anda dan kemudian membandingkannya dengan kinerja puncak sistem.

Jika Anda mendapatkan utilisasi CPU 100%, itu tidak berarti Anda mendapatkan semua kinerja dari sistem. CPU sering kali dapat melakukan banyak hal yang berbeda secara bersamaan, misalnya pembagian dan penambahan. Jika Anda dapat memulai divisi lebih awal, itu mungkin bisa tumpang tindih dengan penambahan. CPU desktop Anda kemungkinan besar memiliki unit out of order yang akan menyusun ulang laporan untuk mendapatkan manfaat dari tumpang tindih tersebut. Atau jika Anda memiliki program berikut:

if (expr1)
    expr2;
else
    expr3;

CPU penataan ulang akan mencoba untuk menghitung tiga ekspresi pada saat yang sama dan kemudian membuang hasil salah satunya. Ini membuatnya lebih cepat secara keseluruhan. Jika Anda memiliki beberapa pemblokir dalam program Anda dan Anda tidak dapat memesan ulang, maka Anda menggunakan lebih sedikit jalur di CPU, tetapi mungkin masih akan menunjukkan 100%.

Kemudian Anda memiliki fitur SIMD di CPU yang merupakan operasi vektor. Ini seperti GPGPU-cahaya dalam arti bahwa Anda biasanya hanya memiliki empat atau delapan operasi pada saat yang sama, GPU memang suka 32 atau 64. Masih Anda harus menggunakannya untuk engkol keluar FLOPS.

Hal-hal seperti berbagi palsu dapat menyebabkan biaya sinkronisasi yang berat yang biasanya muncul sebagai beban kernel di Linux. CPU sepenuhnya digunakan tetapi Anda tidak memiliki banyak throughput yang bermanfaat.

Saya telah melakukan beberapa pemrograman pada mesin IBM Blue Gene / Q. Ia memiliki banyak tingkatan hierarki ( skema Blue Gene / L yang sudah ketinggalan zaman ) dan karenanya sulit diprogram secara efisien. Anda harus menggunakan hierarki lengkap hingga ke SIMD dan SMT (Intel menyebut HyperThreading ini) untuk mendapatkan kinerja yang baik.

Dan kemudian jaringan sering membatasi Anda. Oleh karena itu ternyata lebih cepat dalam waktu (jam dinding) untuk menghitung hal-hal di banyak CPU pada saat yang sama alih-alih berkomunikasi melalui jaringan. Ini akan menempatkan lebih banyak beban pada CPU dan membuat program berjalan lebih cepat. Tetapi throughput program yang sebenarnya tidak sebagus yang terlihat dari angka mentah.

Jika Anda menambahkan GPU ke dalam campuran, akan menjadi semakin sulit untuk mengatur semua ini untuk menghasilkan kinerja. Itu akan menjadi salah satu hal yang akan saya mulai lakukan dalam Tesis Master Lattice QCD saya dalam beberapa bulan.


1

Anda mungkin tertarik untuk memeriksa mesin browser Servo yang sedang dikembangkan di Mozilla Research, dan lebih spesifiknya Web Render (video) .

Sementara mengalihkan tugas dari CPU ke GPU secara dinamis mungkin tidak praktis, seperti yang disebutkan dalam jawaban lain (terutama @ Philip), dapat praktis untuk mempelajari beban CPU / GPU pada beban kerja tipikal di muka dan mengalihkan beberapa tugas ke yang umumnya kurang dimuat satu.

Dalam kasus Web Render, kebaruannya adalah browser secara tradisional melakukan sebagian besar pekerjaan rendering pada CPU (yaitu, CPU digunakan untuk menghitung objek mana yang akan ditampilkan, tempat memotong, dll ...). GPU biasanya lebih baik dalam hal itu ... kecuali bahwa tidak semua usecases sepele untuk diimplementasikan (culling parsial, bayangan, ... dan teks).

Versi awal Web Render terbukti sangat sukses dalam peningkatan kinerja, tetapi tidak mencoba untuk mengatasi masalah rendering teks (dan memiliki beberapa batasan lainnya). Mozilla Research sekarang bekerja pada versi kedua yang dimaksudkan untuk memiliki keterbatasan lebih sedikit, dan terutama untuk mendukung rendering teks.

Tujuannya, tentu saja, adalah untuk memuat sebanyak mungkin proses rendering ke GPU, membiarkan CPU bebas untuk mengeksekusi Javascript, memperbarui DOM, dan semua tugas lainnya.

Jadi, sementara tidak seekstrim saran Anda, itu masuk ke arah merancang strategi perhitungan dengan baik CPU dan GPU dalam pikiran.


0

Dengan fokus pada permainan (karena Anda menyebutkannya secara khusus di pos Anda), ada beberapa cara Anda dapat menyeimbangkan beban. Salah satu contoh adalah "menguliti", yaitu menjiwai model. Untuk setiap frame yang akan dirender, Anda harus membuat matriks transformasi untuk setiap frame animasi dan menerapkannya pada simpul model untuk mengubahnya menjadi pose yang diperlukan. Anda juga harus menginterpolasi frame untuk mendapatkan gerakan yang halus , kecuali Anda ingin animasi Anda terlihat seperti gempa asli (yaitu tersentak-sentak).

Dalam situasi ini, Anda bisa melakukannya pada CPU dan mengunggah hasilnya ke GPU untuk rendering, atau melakukan perhitungan dan rendering pada GPU. Saya percaya saat ini hal ini dilakukan pada GPU (dikenal sebagai "skinning skinning"): masuk akal untuk melakukannya mengingat Anda memiliki perhitungan yang relatif sederhana yang harus dilakukan ribuan kali lipat, dan setiap titik dapat dihitung secara bersamaan karena hasilnya vertex A tidak berpengaruh pada hasil vertex B.

Namun secara teori, Anda dapat beralih secara dinamis antara melakukannya pada CPU atau GPU tergantung pada seberapa kelebihan GPU dan CPU.

Namun pemblokir utama untuk melakukan ini di semua perhitungan adalah bahwa CPU dan GPU memiliki kekuatan dan kelemahan yang berbeda. Pekerjaan paralel besar-besaran lebih baik dilakukan pada GPU, sementara tugas linier intensif dengan percabangan lebih baik dilakukan pada CPU. Hanya beberapa pekerjaan yang secara realistis dapat dilakukan pada keduanya tanpa kinerja yang serius.

Secara keseluruhan, masalah utama dengan pemrograman GPU (setidaknya dengan OpenGL dan DirectX 11 ke bawah) adalah Anda memiliki sedikit kendali atas bagaimana GPU mengartikan kode shader Anda. Bercabang di dalam shader berisiko karena jika Anda secara tidak sengaja membuat ketergantungan di antara perhitungan, maka GPU dapat memutuskan untuk mulai merender piksel Anda satu per satu, mengubah 60fps menjadi 10fps dalam sekejap meskipun data aktual yang dibuat identik.


0

Salah satu contoh dunia nyata adalah mesin render LuxRender open source , yang mampu memuat CPU dan GPU secara bersamaan secara bersamaan. Selain itu, dapat memuat beberapa GPU pada saat yang sama dan juga dapat didistribusikan di beberapa komputer.

LuxRender menggunakan OpenCL untuk memfasilitasi ini, meskipun build tanpa OpenCL juga ada.

Ini praktis karena algoritma yang digunakan LuxRender sangat paralel. Algoritma yang paling umum digunakan LuxRender adalah penelusuran jalur , di mana banyak jalur cahaya individu dapat dihitung secara independen satu sama lain — situasi ideal untuk komputasi GPU dan yang tidak memerlukan sinkronisasi rumit antara node komputasi. Namun, keterbatasan GPU (jumlah memori yang lebih rendah, kurangnya dukungan untuk beberapa fitur rendering yang kompleks, dan kurangnya ketersediaan untuk beberapa seniman) memastikan bahwa dukungan CPU masih penting.


apa gunanya menampilkan gambar ini, bagaimana relevansinya dengan pertanyaan yang diajukan?
nyamuk

1
Ehh baiklah. Saya akan menghapusnya. Saya berpikir itu akan dengan mudah menunjukkan jenis perangkat lunak apa itu. Tapi mungkin itu hanya mengganggu. (Ada banyak jenis mesin rendering; yang satu ini ditargetkan pada still photorealistic.)
PythonNut

0

Ya, tentu saja mungkin.

Komputasi apa pun yang dapat dilakukan CPU, GPU juga dapat dilakukan, dan sebaliknya.

Tapi itu tidak biasa karena:

  • Kompleksitas teknik Meskipun dimungkinkan untuk menjalankan kode yang sama pada CPU dan GPU (misalnya CUDA), prosesor memiliki kemampuan dan karakteristik kinerja yang berbeda. Salah satunya adalah MIMD; yang lainnya, SIMD. Apa yang cepat pada satu lambat di yang lain (misalnya percabangan), sehingga Anda perlu menulis kode terpisah untuk memaksimalkan kinerja.

  • Efisiensi biaya GPU secara agregat jauh lebih kuat daripada CPU. Seluruh gagasan GPU adalah untuk menggunakan prosesor yang lebih murah, lebih lambat, tetapi lebih banyak untuk melakukan komputasi jauh lebih cepat daripada CPU untuk biaya yang sama. GPU lebih hemat biaya dengan satu atau dua urutan besarnya.

Jika Anda menjalankan algoritme pada GPU, lebih baik untuk mengoptimalkannya, dan menambahkan sebanyak yang Anda butuhkan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.