Beranda » bagaimana » Bagaimana CPU dan GPU Berinteraksi untuk Membuat Grafik Komputer?

    Bagaimana CPU dan GPU Berinteraksi untuk Membuat Grafik Komputer?

    Unit Pemrosesan Sentral (CPU) dan Unit Pemrosesan Grafik (GPU) komputer Anda berinteraksi setiap saat Anda menggunakan komputer untuk menghadirkan antarmuka visual yang tajam dan responsif. Baca terus untuk lebih memahami bagaimana mereka bekerja bersama.

    foto oleh sskennel.

    Sesi Tanya Jawab hari ini datang kepada kami dengan izin dari SuperUser-subdivisi Stack Exchange, pengelompokan komunitas yang didorong oleh situs web T&J.

    Pertanyaan

    Pembaca SuperUser Sathya mengajukan pertanyaan:

    Di sini Anda dapat melihat tangkapan layar program C ++ kecil yang disebut Triangle.exe dengan segitiga berputar berdasarkan OpenGL API.

    Diakui contoh yang sangat mendasar tapi saya pikir itu berlaku untuk operasi kartu grafis lainnya.

    Saya hanya ingin tahu dan ingin tahu seluruh proses dari mengklik ganda pada Triangle.exe di bawah Windows XP sampai saya dapat melihat segitiga berputar pada monitor. Yang terjadi, bagaimana CPU (yang pertama menangani .exe) dan GPU (yang akhirnya menampilkan segitiga di layar) berinteraksi?

    Saya kira terlibat dalam menampilkan rotating triangle ini terutama adalah perangkat keras / lunak berikut ini:

    Perangkat keras

    • HDD
    • Memori Sistem (RAM)
    • CPU
    • Memori video
    • GPU
    • layar LCD

    Perangkat lunak

    • Sistem operasi
    • API DirectX / OpenGL
    • Driver Nvidia

    Adakah yang bisa menjelaskan prosesnya, mungkin dengan semacam diagram alur untuk ilustrasi?

    Seharusnya bukan penjelasan yang rumit yang mencakup setiap langkah (tebak yang akan melampaui ruang lingkup), tetapi penjelasan yang bisa diikuti oleh seorang perantara TI.

    Saya cukup yakin banyak orang yang bahkan menyebut diri mereka profesional TI tidak dapat menggambarkan proses ini dengan benar.

    Jawabannya

    Meskipun banyak anggota masyarakat menjawab pertanyaan itu, Oliver Salzburg berusaha keras dan menjawabnya tidak hanya dengan respons terperinci tetapi juga grafik yang sangat baik.

    Gambar oleh JasonC, tersedia sebagai wallpaper di sini.

    Dia menulis:

    Saya memutuskan untuk menulis sedikit tentang aspek pemrograman dan bagaimana komponen saling berbicara. Mungkin itu akan menjelaskan beberapa area tertentu.

    Presentasi

    Apa yang diperlukan bahkan untuk memiliki satu gambar itu, yang Anda poskan di pertanyaan Anda, digambar di layar?

    Ada banyak cara untuk menggambar segitiga di layar. Untuk mempermudah, mari kita asumsikan tidak ada buffer vertex yang digunakan. (SEBUAH buffer vertexadalah area memori tempat Anda menyimpan koordinat.) Mari kita asumsikan program hanya memberi tahu pipeline pemrosesan grafik tentang setiap titik tunggal (titik hanya koordinat dalam ruang) dalam satu baris.

    Tapi, sebelum kita dapat menggambar apa pun, pertama-tama kita harus menjalankan beberapa perancah. Kita lihat saja nanti Mengapa kemudian:

    // Kosongkan Layar Dan Penyangga Kedalaman glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Atur Ulang Matriks Modelview Saat Ini glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Menggambar Menggunakan Segitiga glBegin (GL_TRIANGLES); // Red glColor3f (1.0f, 0.0f, 0.0f); // Top Of Triangle (Depan) glVertex3f (0.0f, 1.0f, 0.0f); // Hijau glColor3f (0,0f, 1.0f, 0.0f); // Kiri Segitiga (Depan) glVertex3f (-1.0f, -1.0f, 1.0f); // Blue glColor3f (0.0f, 0.0f, 1.0f); // Hak Segitiga (Depan) glVertex3f (1.0f, -1.0f, 1.0f); // Selesai menggambar glEnd ();

    Jadi apa yang dilakukannya?

    Saat Anda menulis sebuah program yang ingin menggunakan kartu grafis, biasanya Anda akan memilih semacam antarmuka untuk driver. Beberapa antarmuka yang terkenal untuk driver adalah:

    • OpenGL
    • Direct3D
    • CUDA

    Untuk contoh ini kita akan tetap menggunakan OpenGL. Sekarang, milikmu antarmuka ke pengemudi adalah apa yang memberi Anda semua alat yang Anda butuhkan untuk membuat program Anda berbicara ke kartu grafis (atau driver, yang kemudian pembicaraan ke kartu).

    Antarmuka ini pasti memberi Anda pasti alat. Alat-alat ini berbentuk API yang dapat Anda panggil dari program Anda.

    API itulah yang kami lihat digunakan dalam contoh di atas. Mari kita lihat lebih dekat.

    Perancah

    Sebelum Anda benar-benar dapat melakukan gambar yang sebenarnya, Anda harus melakukan a mempersiapkan. Anda harus mendefinisikan viewport Anda (area yang akan ditampilkan), perspektif Anda (the kamera ke dunia Anda), apa anti-aliasing yang akan Anda gunakan (untuk menghaluskan ujung segitiga Anda) ...

    Tapi kita tidak akan melihat itu. Kami hanya akan mengintip hal-hal yang harus Anda lakukan setiap bingkai. Seperti:

    Menghapus layar

    Pipa grafis tidak akan menghapus layar untuk Anda setiap frame. Anda harus mengatakannya. Mengapa? Ini sebabnya:

    Jika Anda tidak menghapus layar, Anda cukup menepi setiap frame. Itu sebabnya kami menelepon glClear denganGL_COLOR_BUFFER_BIT set. Bit lainnya (GL_DEPTH_BUFFER_BIT) memberitahu OpenGL untuk menghapus kedalamanpenyangga. Buffer ini digunakan untuk menentukan piksel mana yang berada di depan (atau di belakang) piksel lainnya.

    Transformasi


    Sumber gambar

    Transformasi adalah bagian di mana kita mengambil semua koordinat input (simpul segitiga kami) dan menerapkan matriks ModelView kami. Ini adalah matriks itu menjelaskan bagaimana kita model (simpul) diputar, diskalakan, dan diterjemahkan (dipindahkan).

    Selanjutnya, kami menerapkan matriks Proyeksi kami. Ini memindahkan semua koordinat sehingga mereka menghadap kamera kami dengan benar.

    Sekarang kita mengubah sekali lagi, dengan matriks Viewport kami. Kami melakukan ini untuk skala kami model dengan ukuran monitor kami. Sekarang kami memiliki satu set simpul yang siap untuk dirender!

    Kami akan kembali ke transformasi sedikit kemudian.

    Gambar

    Untuk menggambar segitiga, kita cukup memberi tahu OpenGL untuk memulai yang baru daftar segitiga dengan menyebut glBegin dengan GL_TRIANGLES konstan.
    Ada juga formulir lain yang bisa Anda gambar. Seperti strip segitiga atau kipas segitiga. Ini terutama adalah optimasi, karena mereka membutuhkan lebih sedikit komunikasi antara CPU dan GPU untuk menggambar jumlah segitiga yang sama.

    Setelah itu, kami dapat menyediakan daftar set 3 simpul yang harus membentuk setiap segitiga. Setiap segitiga menggunakan 3 koordinat (seperti kita berada dalam ruang 3D). Selain itu, saya juga menyediakan warna untuk setiap titik, dengan meneleponglColor3f sebelum panggilan glVertex3f.

    Bayangan antara 3 simpul (3 sudut segitiga) dihitung oleh OpenGLsecara otomatis. Ini akan menginterpolasi warna di seluruh wajah poligon.

    Interaksi

    Sekarang, ketika Anda mengklik jendela. Aplikasi hanya perlu menangkap pesan jendela yang menandakan klik. Kemudian Anda dapat menjalankan tindakan apa pun di program yang Anda inginkan.

    Ini mendapat banyak lebih sulit setelah Anda ingin mulai berinteraksi dengan adegan 3D Anda.

    Pertama-tama Anda harus mengetahui dengan jelas piksel mana yang diklik pengguna. Lalu, ambil milikmu perspektifmemperhitungkan, Anda dapat menghitung arah sinar, dari titik klik mouse ke adegan Anda. Anda kemudian dapat menghitung jika ada objek dalam adegan Anda berpotongan dengan sinar itu. Sekarang Anda tahu jika pengguna mengklik suatu objek.

    Jadi, bagaimana Anda membuatnya berputar?

    Transformasi

    Saya mengetahui dua jenis transformasi yang umumnya diterapkan:

    • Transformasi berbasis matriks
    • Transformasi berbasis tulang

    Perbedaannya adalah itu tulang mempengaruhi lajang simpul. Matriks selalu mempengaruhi semua simpul yang ditarik dengan cara yang sama. Mari kita lihat sebuah contoh.

    Contoh

    Sebelumnya, kami memuat matriks identitas sebelum menggambar segitiga kami. Matriks identitas adalah salah satu yang hanya menyediakan tidak ada transformasi sama sekali. Jadi, apa pun yang saya gambar, hanya dipengaruhi oleh perspektif saya. Jadi, segitiga tidak akan diputar sama sekali.

    Jika saya ingin memutarnya sekarang, saya bisa melakukan matematika sendiri (pada CPU) dan cukup menelepon glVertex3f denganlain koordinat (yang diputar). Atau saya bisa membiarkan GPU melakukan semua pekerjaan, dengan menelepon glRotatefsebelum menggambar:

    // Putar Segitiga Pada Sumbu Y glRotatef (jumlah, 0.0f, 1.0f, 0.0f); 

    jumlah tentu saja hanyalah nilai tetap. Jika Anda menghendaki menghidupkan, Anda harus melacak jumlahdan tingkatkan setiap frame.

    Jadi, tunggu, apa yang terjadi pada semua pembicaraan matriks sebelumnya?

    Dalam contoh sederhana ini, kita tidak perlu peduli dengan matriks. Kami hanya menelepon glRotatef dan itu mengurus semua itu untuk kita.

    glRotate menghasilkan rotasi sudut derajat di sekitar vektor x y z. Matriks saat ini (seeglMatrixMode) dikalikan dengan matriks rotasi dengan produk yang menggantikan matriks saat ini, seolah-olahglMultMatrix dipanggil dengan matriks berikut sebagai argumennya:

    x 2 ⁡ 1 - c + cx ⁢ y ⁡ 1 - c - z ⁢ sx ⁢ z ⁡ 1 - c + y ⁢ s 0 y ⁢ x ⁡ 1 - c + z ⁢ sy 2 ⁡ 1 - c + cy ⁢ z ⁡ 1 - c - x ⁢ s 0 x ⁢ z ⁡ 1 - c - y ⁢ sy ⁢ z ⁡ 1 - c + x ⁢ sz 2 ⁡ 1 - c + c 0 0 0 0 1 1

    Terima kasih untuk itu!

    Kesimpulan

    Yang menjadi jelas adalah, ada banyak pembicaraan untuk OpenGL. Tapi tidak jelas kami apa pun. Dimana komunikasinya?

    Satu-satunya hal yang dikatakan OpenGL dalam contoh ini adalah ketika selesai. Setiap operasi akan memakan waktu tertentu. Beberapa operasi memakan waktu sangat lama, yang lain sangat cepat.

    Mengirim simpul untuk GPU akan sangat cepat, saya bahkan tidak tahu bagaimana mengekspresikannya. Mengirim ribuan simpul dari CPU ke GPU, setiap frame tunggal, kemungkinan besar, tidak ada masalah sama sekali.

    Menghapus layar dapat memakan waktu milidetik atau lebih buruk (perlu diingat, Anda biasanya hanya memiliki sekitar 16 milidetik waktu untuk menggambar setiap frame), tergantung pada seberapa besar viewport Anda. Untuk menghapusnya, OpenGL harus menggambar setiap piksel dalam warna yang ingin Anda hapus, yang bisa jutaan piksel.

    Selain itu, kami hanya bisa bertanya kepada OpenGL tentang kemampuan adaptor grafis kami (resolusi maks, anti-aliasing max, kedalaman warna maks, ...).

    Tetapi kita juga dapat mengisi tekstur dengan piksel yang masing-masing memiliki warna tertentu. Setiap piksel memiliki nilai dan teksturnya adalah "file" raksasa yang diisi dengan data. Kita dapat memuatnya ke kartu grafis (dengan membuat buffer tekstur), kemudian memuat shader, memberi tahu shader itu untuk menggunakan tekstur kita sebagai input dan menjalankan beberapa perhitungan yang sangat berat pada "file" kita..

    Kami kemudian dapat "membuat" hasil perhitungan kami (dalam bentuk warna baru) ke dalam tekstur baru.

    Itulah cara Anda membuat GPU berfungsi untuk Anda dengan cara lain. Saya menganggap CUDA melakukan hal yang mirip dengan aspek itu, tetapi saya tidak pernah memiliki kesempatan untuk bekerja dengannya.

    Kami benar-benar hanya sedikit menyentuh keseluruhan subjek. Pemrograman grafis 3D adalah binatang buas.


    Sumber Gambar


    Punya sesuatu untuk ditambahkan ke penjelasan? Berbunyi dalam komentar. Ingin membaca lebih banyak jawaban dari pengguna Stack Exchange yang mengerti teknologi lainnya? Lihat utas diskusi lengkap di sini.