Laman » bagaimana untuk » Bagaimana CPU dan GPU Berinteraksi untuk Menampilkan Grafik Komputer?

    Bagaimana CPU dan GPU Berinteraksi untuk Menampilkan Grafik Komputer?

    Unit Pemprosesan Tengah (CPU) dan Unit Pemprosesan Grafik (GPU) komputer anda berinteraksi setiap saat menggunakan komputer anda untuk memberikan anda antara muka visual yang jernih dan responsif. Teruskan membaca untuk lebih memahami bagaimana mereka bekerja bersama.

    gambar dari sskennel.

    Sesi Soalan & Jawapan hari ini datang kepada kami dengan hormat SuperUser-satu bahagian pembahagian Stack Exchange, kumpulan pemanduan komuniti laman web Q & A.

    Soalan

    Pembaca SuperUser Sathya menimbulkan persoalan:

    Di sini anda dapat melihat tangkapan skrin kecil C ++ yang dipanggil Triangle.exe dengan segitiga berputar berdasarkan API OpenGL.

    Diakui contoh yang sangat asas tetapi saya fikir ia boleh digunakan untuk operasi kad grafik lain.

    Saya hanya ingin tahu dan ingin mengetahui keseluruhan proses daripada mengklik dua kali pada Triangle.exe di bawah Windows XP sehingga saya dapat melihat segitiga berputar di monitor. Apa yang berlaku, bagaimana CPU (yang pertama menangani .exe) dan GPU (yang akhirnya menghasilkan segitiga pada layar) berinteraksi?

    Saya rasa terlibat dalam memaparkan segitiga berputar adalah terutamanya perkakasan / perisian berikut antara lain:

    Perkakasan

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

    Perisian

    • Sistem operasi
    • DirectX / OpenGL API
    • Pemandu Nvidia

    Bolehkah sesiapa menjelaskan proses itu, mungkin dengan beberapa carta aliran untuk ilustrasi?

    Ia tidak sepatutnya menjadi penjelasan yang rumit yang meliputi setiap langkah (kira-kira yang akan melampaui skop), tetapi penjelasan seorang lelaki IT perantaraan boleh mengikuti.

    Saya cukup pasti ramai orang yang akan memanggil diri mereka profesional IT tidak dapat menerangkan proses ini dengan betul.

    Jawapan

    Walaupun beberapa ahli komuniti menjawab soalan tersebut, Oliver Salzburg pergi lebih jauh dan menjawabnya bukan sahaja dengan respons terperinci tetapi grafik yang disertakan dengan cemerlang.

    Imej oleh JasonC, tersedia sebagai kertas dinding di sini.

    Dia menulis:

    Saya memutuskan untuk menulis sedikit tentang aspek pengaturcaraan dan bagaimana komponen bercakap antara satu sama lain. Mungkin ia akan memberi sedikit cahaya pada kawasan tertentu.

    Persembahan itu

    Apa yang diperlukan untuk mempunyai imej tunggal itu, yang anda hantar dalam soalan anda, ditarik pada skrin?

    Terdapat banyak cara untuk menarik segitiga pada skrin. Untuk kesederhanaan, mari kita asumsikan tiada buffer penunjuk digunakan. (A penyangga puncakadalah kawasan ingatan di mana anda menyimpan koordinat.) Mari kita asumsikan program itu hanya memberitahu pipeline pemprosesan grafik mengenai setiap titik puncak (titik puncak adalah koordinat dalam ruang) berturut-turut.

    Tetapi, sebelum kita boleh menarik apa-apa, kita perlu terlebih dahulu menjalankan beberapa perancah. Kita akan lihat kenapa kemudian:

    // Kosongkan Skrin Dan Buffer Kedalaman glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Reset Matriks Modelview semasa glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Menggambar Menggunakan Triangles glBegin (GL_TRIANGLES); // Red glColor3f (1.0f, 0.0f, 0.0f); // Top Of Triangle (Depan) glVertex3f (0.0f, 1.0f, 0.0f); // Green glColor3f (0.0f, 1.0f, 0.0f); / // Kiri Segitiga (Hadapan) glVertex3f (-1.0f, -1.0f, 1.0f); // Blue glColor3f (0.0f, 0.0f, 1.0f); // Right Of Triangle (Front) glVertex3f (1.0f, -1.0f, 1.0f); / // Lukisan Selesai glEnd ();

    Jadi apa yang berlaku?

    Apabila anda menulis program yang ingin menggunakan kad grafik, biasanya anda akan memilih beberapa jenis antara muka kepada pemandu. Sesetengah antara muka yang terkenal kepada pemandu adalah:

    • OpenGL
    • Direct3D
    • CUDA

    Untuk contoh ini kami akan melekat dengan OpenGL. Sekarang, anda antara muka dengan pemandu adalah apa yang memberi anda semua alat yang anda perlukan untuk membuat program anda bercakap ke kad grafik (atau pemandu, yang kemudiannya ceramah ke kad).

    Antara muka ini pasti memberi anda pasti alat. Alat ini mengambil bentuk API yang boleh anda panggil dari program anda.

    API itu adalah apa yang kita lihat digunakan dalam contoh di atas. Mari lihat lebih dekat.

    Perancah

    Sebelum anda benar-benar boleh melakukan apa-apa lukisan sebenar, anda perlu melaksanakan persediaan. Anda perlu menentukan port pandangan anda (kawasan yang sebenarnya akan diberikan), perspektif anda (yang kamera ke dalam dunia anda), apa yang anti-aliasing anda akan gunakan (untuk melicinkan tepi segi tiga anda) ...

    Tetapi kita tidak akan melihat apa-apa itu. Kami hanya akan mengintip perkara yang perlu anda lakukan setiap bingkai. Suka:

    Membersihkan skrin

    Talian paip grafik tidak akan membersihkan skrin untuk anda setiap bingkai. Anda perlu memberitahunya. Mengapa? Inilah sebabnya:

    Jika anda tidak membersihkan skrin, anda hanya akan lukiskan ia setiap bingkai. Itulah sebabnya kita panggil glClear denganGL_COLOR_BUFFER_BIT ditetapkan. Yang lain (GL_DEPTH_BUFFER_BIT) memberitahu OpenGL untuk membersihkannya kedalamanpenampan. Penampan ini digunakan untuk menentukan piksel mana di depan (atau di belakang) piksel lain.

    Transformasi


    Sumber imej

    Transformasi ialah bahagian di mana kita mengambil semua koordinat input (simpang segitiga kita) dan menggunakan matriks ModelView kami. Inilah matriks itu menerangkan bagaimana kita model (simpul) diputar, dinyalakan, dan diterjemahkan (bergerak).

    Seterusnya, kami menggunakan Matriks Perancangan kami. Ini bergerak semua koordinat supaya mereka menghadapi kamera kami dengan betul.

    Sekarang kita mengubah sekali lagi, dengan Matriks Viewport kita. Kami melakukan ini untuk skala kami model untuk saiz monitor kami. Sekarang kita mempunyai satu set serikat yang siap untuk diberikan!

    Kami akan kembali kepada transformasi sedikit kemudian.

    Lukisan

    Untuk melukis segitiga, kita hanya boleh memberitahu OpenGL untuk memulakan yang baru senarai segitiga dengan memanggil glBegin dengan GL_TRIANGLES berterusan.
    Terdapat juga bentuk lain yang boleh anda gambarkan. Seperti jalur segitiga atau kipas segitiga. Ini adalah terutamanya pengoptimuman, kerana mereka memerlukan kurang komunikasi antara CPU dan GPU untuk menarik jumlah yang sama segitiga.

    Selepas itu, kami dapat menyediakan satu senarai set 3 titik yang harus membentuk setiap segitiga. Setiap segitiga menggunakan 3 koordinat (seperti dalam ruang 3D). Di samping itu, saya juga menyediakan warna untuk setiap puncak, dengan menelefonglColor3f sebelum ini memanggil glVertex3f.

    Bayangan antara 3 simpang (3 sudut segitiga) dikira oleh OpenGLsecara automatik. Ia akan menginterpolasi warna di seluruh permukaan poligon.

    Interaksi

    Sekarang, apabila anda mengklik tetingkap. Permohonan hanya perlu menangkap mesej tetingkap yang menandakan klik. Kemudian anda boleh menjalankan sebarang tindakan dalam program anda yang anda mahukan.

    Ini mendapat a banyak lebih sukar apabila anda mahu berinteraksi dengan adegan 3D anda.

    Anda perlu tahu dengan jelas di mana piksel pengguna mengklik tetingkap. Kemudian, ambil awak perspektifkira, anda boleh mengira arah sinar, dari titik klik tetikus ke tempat kejadian anda. Anda boleh mengira jika ada objek di tempat kejadian anda bersilang dengan sinar itu. Sekarang anda tahu jika pengguna mengklik objek.

    Jadi, bagaimana anda membuatnya berputar?

    Transformasi

    Saya sedar tentang dua jenis transformasi yang biasanya digunakan:

    • Transformasi berasaskan matriks
    • Transformasi berasaskan tulang

    Perbezaannya ialah tulang menjejaskan tunggal mercu. Matriks sentiasa menjejaskan semua simpul yang ditarik dengan cara yang sama. Mari lihat contoh.

    Contoh

    Terdahulu, kami memuatkan kami matriks identiti sebelum melukis segitiga kami. Matriks identiti adalah yang hanya menyediakan tiada perubahan sama sekali. Jadi, apa sahaja yang saya buat, hanya dipengaruhi oleh perspektif saya. Jadi, segitiga tidak akan diputar sama sekali.

    Jika saya mahu memutarkannya sekarang, saya boleh melakukan matematik sendiri (pada CPU) dan hanya memanggilnya glVertex3f denganlain koordinat (yang diputar). Atau saya boleh biarkan GPU melakukan semua kerja, dengan memanggil glRotatefsebelum melukis:

    // Putar Segitiga Pada Y axis glRotatef (amaun, 0.0f, 1.0f, 0.0f); 

    jumlah adalah, sememangnya, hanya nilai tetap. Jika anda mahu bernyawa, anda perlu mengesan jumlahdan menambah setiap bingkai.

    Jadi, tunggu apa yang berlaku kepada semua perbualan matriks tadi?

    Dalam contoh mudah ini, kita tidak perlu mengambil berat mengenai matriks. Kami hanya menelefon glRotatef dan ia menjaga semua itu untuk kita.

    glRotate menghasilkan putaran sudut darjah sekitar vektor x y z. Matriks semasa (seeglMatrixMode) didarab dengan matriks putaran dengan produk menggantikan matriks semasa, seperti ifMultMatrix dipanggil dengan matriks berikut sebagai hujahnya:

    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

    Baiklah, terima kasih untuk itu!

    Kesimpulannya

    Apa yang menjadi jelas ialah, banyak bercakap kepada OpenGL. Tetapi ia tidak mengatakan kami apa sahaja. Di mana komunikasi itu?

    Satu-satunya perkara yang OpenGL memberitahu kita dalam contoh ini ialah apabila ia selesai. Setiap operasi akan mengambil masa tertentu. Sesetengah operasi mengambil masa yang sangat lama, yang lain sangat cepat.

    Menghantar hujung untuk GPU akan begitu cepat, saya tidak akan tahu bagaimana untuk menyatakannya. Menghantar ribuan simptom dari CPU ke GPU, setiap bingkai tunggal, kemungkinan besar, tidak ada masalah sama sekali.

    Membersihkan skrin boleh mengambil milisaat atau lebih buruk (ingatlah, biasanya anda hanya mempunyai kira-kira 16 milisaat masa untuk menarik setiap bingkai), bergantung kepada berapa besar viewport anda. Untuk mengosongkannya, OpenGL perlu menarik setiap piksel tunggal dalam warna yang anda ingin jelaskan, yang boleh berjuta-juta piksel.

    Selain itu, kami hanya boleh bertanya kepada OpenGL mengenai keupayaan penyesuai grafik kami (resolusi maksimum, anti-aliasing maksimum, kedalaman warna max, ...).

    Tetapi kita juga boleh mengisi tekstur dengan piksel yang masing-masing mempunyai warna tertentu. Setiap piksel itu memegang nilai dan tekstur adalah "fail" yang dipenuhi dengan data. Kita boleh memuatkannya ke dalam kad grafik (dengan mencipta penampan tekstur), kemudian memuatkan shader, beritahu shader itu untuk menggunakan tekstur kami sebagai input dan jalankan beberapa pengiraan yang sangat berat pada "fail".

    Kita boleh "menjadikan" keputusan pengiraan kami (dalam bentuk warna baru) menjadi tekstur baru.

    Itulah bagaimana anda boleh membuat kerja GPU untuk anda dengan cara lain. Saya menganggap CUDA sama seperti aspek itu, tetapi saya tidak pernah mempunyai peluang untuk bekerja dengannya.

    Kami benar-benar hanya menyentuh keseluruhan subjek. Pengaturcaraan grafik 3D adalah neraka binatang.


    Sumber Imej


    Mempunyai sesuatu untuk menambah penjelasannya? Bunyi dalam komen. Ingin membaca lebih banyak jawapan dari pengguna Stack Exchange yang berteknologi tinggi? Lihat thread perbincangan penuh di sini.