Akses memori yang optimal saat menggunakan tabel pencarian pada GPU?

9

Saya menjelajahi algoritma isosurface pada GPU untuk proyek bujangan (khusus berkonsentrasi hanya pada data voxel biner masuk / keluar daripada bidang bernilai nyata). Jadi saya memiliki implementasi CPU dari kubus berbaris tua yang baik dan berjalan di OpenFrameworks, dan sekarang pada tahap mencoba untuk port ke shaders komputasi GLSL, dan mempertimbangkan perangkap sebelum saya menyelam. Saya hanya menulis shader vert dan frag sebelum jadi itu semua baru bagi saya.

Masalah pertama saya adalah bagaimana cara efisien menggunakan tabel pencarian di lusinan atau ratusan utas di workgroup? Saya mengerti GPU memiliki jenis memori yang berbeda untuk tugas yang berbeda tetapi tidak sepenuhnya yakin tentang bagaimana masing-masing beroperasi atau jenis yang digunakan.

Tabel copypasta klasik Paul Bourke adalah array 256 * 16 jadi jika menggunakan tipe byte skalar ini mungkin dapat dikemas ke dalam tekstur 4kb atau SSBO.

Pertanyaannya adalah, bagaimana cara menghentikan utas yang berbeda agar tidak saling tersandung? Banyak kubus di masing-masing kelompok kerja berpotensi memiliki konfigurasi yang sama karena itu mencoba mengakses lokasi yang sama di buffer pada saat yang sama. Apakah ada solusi atau optimasi untuk mengatasi ini?

russ
sumber
Jika ini adalah tabel pencarian hanya-baca, Anda bisa menggunakan buffer / tekstur. Anda dapat mengemasnya ke dalam salah satu format tekstur normal, atau Anda dapat menggunakan beberapa fitur DX11 / OpenGL yang lebih baru untuk memiliki format kustom. UAV di tanah DX11, atau tekstur / shader_image_load_store di tanah OpenGL.
RichieSams
Selain itu, lihat presentasi ini: cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdf Ini untuk CUDA, tetapi harus memberi Anda gagasan yang lebih baik tentang apa yang terjadi pada perangkat keras yang mendasarinya
RichieSams
Bukan jawaban lengkap tetapi semakin sedikit jumlah memori yang Anda gunakan semakin baik, karena akan cenderung lebih cocok dengan cache dan memiliki lebih sedikit cache yang hilang. Jika Anda memiliki nilai interpolatable, seperti Anda sedang membuat poin pada kurva ke dalam tekstur, Anda mungkin memeriksanya sebagai cara untuk mendapatkan tabel pencarian kurva kualitas yang lebih tinggi dengan memori lebih sedikit: blog.demofox.org/2016/02/22/…
Alan Wolfe

Jawaban:

6

Tempat terbaik untuk meletakkan tabel pencarian untuk penghitung komputasi GPU tergantung pada ukuran tabel pencarian, dan frekuensi / koherensi akses. Dalam kasus Anda (Anda menyebutkan 4kb), memori lokal bersama mungkin yang terbaik (dengan asumsi Anda tidak memerlukan memori ini untuk keperluan lain di kernel yang sama). Memori ini memiliki nama yang berbeda di API yang berbeda, tetapi merupakan hal arsitektur yang sama dan mengikuti pedoman kinerja yang sama:

  • CUDA: memori bersama threadgroup
  • DirectCompute: memori grup bersama
  • OpenCL: memori lokal
  • Logam: memori threadgroup
  • OpenGL: memori bersama

Menyimpan tabel pencarian dalam memori global sebagai buffer hanya-baca dapat bekerja dengan baik, tergantung pada ukuran cache GPU tertentu yang Anda jalankan.

Perhatikan bahwa saya menganggap ini adalah tabel pencarian hanya-baca. Tabel pencarian baca-tulis adalah binatang yang sama sekali berbeda, dan Anda tidak memiliki opsi yang bagus di sana.

GroverManheim
sumber
Ada juga kasus di mana buffer read-only akan melakukan lebih baik daripada menyimpan data read-only 4kb dalam memori lokal bersama. Misalnya, menyimpannya di memori lokal dapat berarti bahwa ada salinan unik dari data Anda untuk setiap grup utas. Jika buffer sesuai dengan cache, sangat mungkin bahwa cache berkinerja lebih baik daripada memori lokal untuk pola akses hanya baca.
John Calsbeek
Terima kasih atas tanggapan kalian. Saya telah menyelesaikan proyek yang saya gunakan ini untuk saat ini, dan akhirnya hanya menggunakan tekstur buffer read8ly r8ui, yang bekerja dengan sangat baik :)
russ