Streaming data ke kernel CUDA tanpa banyak peluncuran

Saya mencoba mempercepat algoritma GPU di mana saya menerima aliran partikel asinkron dalam ruang 3D $p=[x,y,t]$. Setiap vektor $p_n$ perlu dikalikan dengan sekumpulan matriks transformasi. Karena transformasi ini tidak bergantung satu sama lain, transformasi ini dapat terjadi secara paralel, jadi saya telah menulis kernel CUDA untuk melakukan itu. Ini berfungsi dengan baik, tetapi tentu saja untuk setiap $p_n$ yang masuk saya akhirnya meluncurkan kernel CUDA lagi. Meluncurkan kernel CUDA memerlukan penalti waktu yang besar, sehingga saya kehilangan keuntungan dari akselerasi GPU. Jadi pertanyaan saya adalah, bisakah saya membiarkan kernel tetap terbuka dan mengalirkan partikel ke dalamnya?

Jika ada bantuan, inilah kernel saya saat ini:

__global__
void project(float *projection_matrix, float *vector, float *output_matrix) {
    int col_index = blockIdx.x * blockDim.x + threadIdx.x;
    int row_index = blockIdx.y * blockDim.x + threadIdx.y;
    int output_index = (col_index*3 + threadIdx.y);
    int transform_first_element = col_index * 9 + threadIdx.y * 3;
    int stride = blockDim.x*blockDim.y*gridDim.x;

    while (output_index < (NUMBER_OF_TRANSFORMS * 3)) {
        output_matrix[output_index] = projection_matrix[transform_first_element]*vector[0]+ projection_matrix[(transform_first_element+1)]*vector[1] + projection_matrix[(transform_first_element+2)]*vector[2];
        output_index += stride;
    }
}

dan di sinilah saya menyebutnya:

...
project <<<num_blocks_dim, block_dim >>> (transformationList, inputVector, outputMatrix);
cudaDeviceSynchronize();
...

person Mr Squid    schedule 26.10.2017    source sumber
comment
Ya, Anda dapat membiarkan kernel tetap terbuka dan mengalirkan partikel ke dalamnya. Ini disebut sebagai paradigma desain kernel yang persisten, dan ada makalah yang ditulis tentangnya serta pertanyaan di SO tentang hal itu.   -  person Robert Crovella    schedule 26.10.2017
comment
@RobertCrovella - Terima kasih atas balasan Anda, ini memberi saya banyak kata kunci bagus untuk ditindaklanjuti yang mungkin tidak saya ketahui sebelumnya. Saya menemukan contoh yang ditata dengan baik ini - sebenarnya Anda menulisnya! (stackoverflow.com/questions/33150040/). Apakah desain produsen/konsumen seperti ini adalah sesuatu yang Anda rekomendasikan untuk kasus penggunaan saya? Akankah seseorang melakukannya dengan cara yang berbeda saat ini dibandingkan pada tahun 2015?   -  person Mr Squid    schedule 27.10.2017
comment
Saya tidak melihat cukup deskripsi kasus penggunaan Anda untuk membuat rekomendasi. Saya terutama menjawab pertanyaan, bisakah saya menjaga kernel tetap terbuka dan mengalirkan partikel ke dalamnya?. Perubahan yang akan saya lakukan hari ini dibandingkan tahun 2015 adalah menggunakan kelompok kooperatif - sebuah fitur baru di CUDA 9 - untuk mengelola desain kernel yang persisten.   -  person Robert Crovella    schedule 27.10.2017


Jawaban (1)


Anda harus mengelompokkan permintaan ke dalam blok yang lebih besar dan memanggil kernel pada banyak partikel. Anda mungkin dapat menggunakan dimensi ketiga dari kernel untuk mengulanginya. Salah satu cara untuk melakukan ini adalah dengan mengakumulasi partikel yang masuk saat kernel sedang berjalan. Jika Anda tidak mendapatkan cukup partikel untuk membenarkan peluncuran kernel, proseskan partikel tersebut di CPU.

Jika partikel diproduksi di GPU, Anda memiliki opsi untuk meluncurkan kernel dari kernel dengan versi CUDA yang lebih baru, namun Anda masih memerlukan blok yang cukup besar untuk mewujudkannya.

Jika ini berasal dari CPU dan kemudian kembali ke CPU, saya akan terkejut jika Anda dapat membuatnya membuahkan hasil kecuali jumlah matriksnya cukup besar. (Dibandingkan dengan kode CPU SIMD yang dioptimalkan dengan baik.)

person Zalman Stern    schedule 26.10.2017
comment
@ZalmanStein Saya belum mempertimbangkan SIMD sebagai alternatif. Saya tentu tidak ingin mulai belajar tentang SSE karena tampaknya sangat rumit bagi saya, tetapi menurut Anda saya mungkin dapat mencapai apa yang saya inginkan dengan perpustakaan tingkat yang lebih tinggi seperti Intel MKL? Sebagai aturan praktis, dalam kasus penggunaan manakah saya harus mempertimbangkan untuk menggunakan CPU SIMD daripada akselerasi GPU? - person Mr Squid; 27.10.2017
comment
Masalah utamanya adalah biaya aliran data. Terdapat overhead tetap dalam mentransfer sebagian kecil data ke/dari GPU dan akan memerlukan banyak komputasi agar hal ini bermanfaat. Kunjungi Halide, halide-lang.org. Ini memungkinkan penulisan kode sedemikian rupa sehingga memungkinkan penargetan CPU dan GPU secara efisien. (Tentu saja tergantung pada spesifiknya. Sebagai penafian, saya mengerjakan Halide.) - person Zalman Stern; 27.10.2017