Saya telah menggunakan CUDA selama beberapa minggu, tetapi saya memiliki keraguan tentang alokasi blok / warps / utas. Saya mempelajari arsitektur dari sudut pandang didaktik (proyek universitas), jadi mencapai kinerja puncak bukan urusan saya.
Pertama-tama, saya ingin memahami jika saya mengemukakan fakta-fakta ini:
Programmer menulis kernel, dan mengatur pelaksanaannya dalam kotak blok thread.
Setiap blok ditugaskan ke Streaming Multiprocessor (SM). Setelah ditugaskan itu tidak dapat bermigrasi ke SM lain.
Setiap SM membagi bloknya sendiri menjadi Warps (saat ini dengan ukuran maksimum 32 utas). Semua utas dalam warp dieksekusi bersamaan pada sumber daya SM.
Eksekusi aktual sebuah thread dilakukan oleh CUDA Cores yang terkandung dalam SM. Tidak ada pemetaan khusus antara utas dan inti.
Jika sebuah warp berisi 20 utas, tetapi saat ini hanya ada 16 core yang tersedia, warp tidak akan berjalan.
Di sisi lain, jika sebuah blok berisi 48 utas, ia akan dibagi menjadi 2 lungsin dan akan dieksekusi secara paralel asalkan tersedia cukup memori.
Jika sebuah thread dimulai pada sebuah core, maka itu macet untuk akses memori atau untuk operasi floating point yang panjang, pelaksanaannya dapat dilanjutkan pada core yang berbeda.
Apakah mereka benar
Sekarang, saya memiliki GeForce 560 Ti sehingga sesuai dengan spesifikasi dilengkapi dengan 8 SM, masing-masing berisi 48 core CUDA (total 384 core).
Tujuan saya adalah memastikan bahwa setiap inti arsitektur mengeksekusi instruksi SAMA. Dengan asumsi bahwa kode saya tidak akan memerlukan lebih banyak register daripada yang tersedia di setiap SM, saya membayangkan pendekatan yang berbeda:
Saya membuat 8 blok dari 48 utas masing-masing, sehingga setiap SM memiliki 1 blok untuk dieksekusi. Dalam hal ini akankah 48 thread dieksekusi secara paralel di SM (mengeksploitasi semua 48 core yang tersedia untuk mereka)?
Apakah ada perbedaan jika saya meluncurkan 64 blok dari 6 utas? (Dengan asumsi bahwa mereka akan dipetakan secara merata di antara SM)
Jika saya "menenggelamkan" GPU dalam pekerjaan terjadwal (membuat 1024 blok masing-masing 1024 utas, misalnya) apakah masuk akal untuk menganggap bahwa semua inti akan digunakan pada titik tertentu, dan akan melakukan perhitungan yang sama (dengan asumsi bahwa utas tidak pernah warung)?
Apakah ada cara untuk memeriksa situasi ini menggunakan profiler?
Apakah ada referensi untuk barang ini? Saya membaca panduan Pemrograman CUDA dan bab-bab yang didedikasikan untuk arsitektur perangkat keras dalam "Pemrograman Proses Masif Paralel" dan "Desain dan pengembangan aplikasi CUDA"; tetapi saya tidak bisa mendapatkan jawaban yang tepat.
sumber
Jawaban:
Dua referensi terbaik adalah
Saya akan mencoba menjawab setiap pertanyaan Anda.
Programmer membagi pekerjaan menjadi utas, utas menjadi blok-blok thread, dan blok-blok thread menjadi grid. Distributor pekerjaan komputasi mengalokasikan blok thread ke Streaming Multiprocessors (SMs). Setelah blok thread didistribusikan ke SM, sumber daya untuk blok thread dialokasikan (lungsin dan memori bersama) dan utas dibagi ke dalam kelompok 32 utas yang disebut warps. Setelah sebuah warp dialokasikan, itu disebut warp aktif. Kedua penjadwal warp memilih dua warps aktif per siklus dan mengirimkan warps ke unit eksekusi. Untuk detail lebih lanjut tentang unit eksekusi dan pengiriman instruksi lihat 1 hal.7-10 dan 2 .
4' . Ada pemetaan antara laneid (indeks thread dalam warp) dan inti.
5 ' . Jika sebuah warp mengandung kurang dari 32 utas, dalam kebanyakan kasus akan dieksekusi sama seperti jika memiliki 32 utas. Warps dapat memiliki kurang dari 32 utas aktif karena beberapa alasan: jumlah utas per blok tidak dapat dibagi oleh 32, program menjalankan blok divergen sehingga utas yang tidak mengambil jalur saat ini ditandai tidak aktif, atau utas di warp keluar.
6 ' . Blok thread akan dibagi menjadi WarpsPerBlock = (ThreadsPerBlock + WarpSize - 1) / WarpSize Tidak ada persyaratan bagi penjadwal warp untuk memilih dua warps dari blok thread yang sama.
7 ' . Unit eksekusi tidak akan menghentikan operasi memori. Jika sumber daya tidak tersedia ketika instruksi siap dikirim, instruksi akan dikirim lagi di masa mendatang ketika sumber daya tersedia. Lengkungan dapat terhenti pada hambatan, pada operasi memori, operasi tekstur, dependensi data, ... Lengkungan yang terhenti tidak memenuhi syarat untuk dipilih oleh penjadwal warp. Pada Fermi, berguna untuk memiliki setidaknya 2 warps yang memenuhi syarat per siklus sehingga penjadwal warp dapat mengeluarkan instruksi.
Lihat referensi 2 untuk perbedaan antara GTX480 dan GTX560.
Jika Anda membaca materi referensi (beberapa menit) saya pikir Anda akan menemukan bahwa tujuan Anda tidak masuk akal. Saya akan mencoba menanggapi poin Anda.
1 ' . Jika Anda meluncurkan kernel <<< 8, 48 >>> Anda akan mendapatkan 8 blok masing-masing dengan 2 lilitan 32 dan 16 utas. Tidak ada jaminan bahwa 8 blok ini akan ditugaskan untuk SM yang berbeda. Jika 2 blok dialokasikan ke SM maka ada kemungkinan bahwa setiap penjadwal warp dapat memilih warp dan mengeksekusi warp. Anda hanya akan menggunakan 32 dari 48 core.
2 ' . Ada perbedaan besar antara 8 blok 48 thread dan 64 blok 6 thread. Mari kita asumsikan bahwa kernel Anda tidak memiliki divergensi dan setiap utas mengeksekusi 10 instruksi.
Untuk mendapatkan efisiensi yang optimal, pembagian pekerjaan harus dalam kelipatan 32 utas. Perangkat keras tidak akan menyatukan utas dari warps yang berbeda.
3 ' . GTX560 dapat memiliki 8 blok SM * 8 = 64 blok sekaligus atau 8 SM * 48 warps = 512 warps jika kernel tidak memaksimalkan register atau memori bersama. Pada waktu tertentu sebagian pekerjaan akan aktif di SM. Setiap SM memiliki beberapa unit eksekusi (lebih dari inti CUDA). Sumber daya mana yang digunakan pada waktu tertentu tergantung pada penjadwalan warp dan campuran instruksi aplikasi. Jika Anda tidak melakukan operasi TEX maka unit TEX akan menganggur. Jika Anda tidak melakukan operasi floating point khusus, unit SUFU akan menganggur.
4' . Paralel Nsight dan pertunjukan Visual Profiler
Sebuah. IPC dieksekusi
b. mengeluarkan IPC
c. warps aktif per siklus aktif
d. warps yang memenuhi syarat per siklus aktif (hanya Nsight)
e. alasan warp warung (khusus Nsight)
f. utas aktif per instruksi dieksekusi
Profiler tidak menunjukkan persentase pemanfaatan unit eksekusi mana pun. Untuk GTX560, perkiraan kasar akan dikeluarkan IssIPIP / MaxIPC. Untuk MaxIPC anggap GF100 (GTX480) adalah 2 GF10x (GTX560) adalah 4 tetapi target 3 adalah target yang lebih baik.
sumber
"E. Jika sebuah warp berisi 20 utas, tetapi saat ini hanya ada 16 inti yang tersedia, warp tidak akan berjalan."
salah. Anda adalah core yang membingungkan dalam pengertian biasanya (juga digunakan dalam CPU) - jumlah "multiprosesor" dalam GPU, dengan core dalam bahasa pemasaran nVIDIA ("kartu kami memiliki ribuan core CUDA").
Sebuah warp itu sendiri hanya dapat dijadwalkan pada satu inti (= multiprosesor), dan dapat berjalan hingga 32 utas pada saat yang sama; tidak dapat menggunakan lebih dari satu inti.
Angka "48 warps" adalah jumlah maksimum warp aktif (warps yang dapat dipilih untuk dijadwalkan untuk bekerja pada siklus berikutnya, pada siklus apa pun yang diberikan) per multiprosesor, pada GPU nVIDIA dengan Kemampuan Komputasi 2.x; dan jumlah ini sesuai dengan 1536 = 48 x 32 utas.
Jawaban berdasarkan webinar ini
sumber