Apa itu konflik bank? (Melakukan pemrograman Cuda / OpenCL)

95

Saya telah membaca panduan pemrograman untuk CUDA dan OpenCL, dan saya tidak tahu apa itu konflik bank. Mereka hanya menyelami bagaimana memecahkan masalah tanpa menguraikan subjek itu sendiri. Adakah yang bisa membantu saya memahaminya? Saya tidak memiliki preferensi jika bantuan tersebut dalam konteks CUDA / OpenCL atau hanya konflik bank secara umum dalam ilmu komputer.

smuggledPancakes
sumber

Jawaban:

105

Untuk nvidia (dan amd dalam hal ini) gpus memori lokal dibagi menjadi bank memori. Setiap bank hanya dapat menangani satu dataset pada satu waktu, jadi jika halfwarp mencoba untuk memuat / menyimpan data dari / ke bank yang sama, akses harus dilakukan secara serial (ini adalah konflik bank). Untuk gt200 gpus ada 16 bank (32 bank untuk fermi), 16 atau 32 bank untuk AMD gpus (57xx atau lebih tinggi: 32, semuanya di bawah: 16)), yang disisipkan dengan granuitas 32bit (jadi byte 0-3 ada di bank 1, 4-7 di bank 2, ..., 64-69 di bank 1 dan seterusnya). Untuk visualisasi yang lebih baik, pada dasarnya terlihat seperti ini:

Bank    |      1      |      2      |      3      |...
Address |  0  1  2  3 |  4  5  6  7 |  8  9 10 11 |...
Address | 64 65 66 67 | 68 69 70 71 | 72 73 74 75 |...
...

Jadi jika setiap utas di halfwarp mengakses nilai 32bit berturut-turut, tidak ada konflik bank. Pengecualian dari aturan ini (setiap utas harus mengakses banknya sendiri) disiarkan: Jika semua utas mengakses alamat yang sama, nilainya hanya dibaca sekali dan disiarkan ke semua utas (untuk GT200 harus semua utas di halfwarp mengakses alamat yang sama, iirc fermi dan AMD gpus dapat melakukan ini untuk sejumlah utas yang mengakses nilai yang sama).

Grizzly
sumber
3
Terima kasih yang manis untuk visual dan penjelasannya. Saya tidak tahu tentang siaran dan sepertinya itu informasi yang penting :) Bagaimana saya akan memverifikasi bahwa muatan dan penyimpanan saya tidak menyebabkan konflik bank di memori bersama? Apakah saya harus mengetahui kode assemblynya atau apakah ada cara lain?
smuggledPancakes
3
karena terjadinya konflik bank adalah suatu pemikiran yang akan ditentukan pada saat runtime (artinya kompilator tidak mengetahuinya, setelah semua sebagian besar alamat dibuat saat runtime), mendapatkan versi yang dikompilasi tidak akan banyak membantu. Saya biasanya melakukan ini dengan cara lama, artinya saya mengambil pena dan kertas dan mulai memikirkan tentang apa yang disimpan kode saya di mana. Lagipula aturan yang mengatur terjadinya konflik bank tidaklah serumit itu. Jika tidak, Anda dapat menggunakan nvidia OpenCL profiler (harus dipaketkan dengan sdk, iirc). Saya pikir itu memiliki counter untuk warp serializes.
Grizzly
1
Terima kasih telah menunjukkan serialisasi warp. Salah satu file teks readme yang disertakan dengan compute profiler mengatakan ini,
smuggledPancakes
1
Ack, permisi komentar di atas, entah kenapa saya tidak bisa edit ulang. Bagaimanapun, saya menemukan ini di readme profiler komputasi, "warp_serialize: Jumlah thread warps yang membuat serial pada konflik alamat ke memori bersama atau konstan." Ini bagus sehingga saya dapat dengan mudah melihat apakah ada konflik hanya dengan melihat output profiler. Bagaimana Anda mengetahui jika ada konflik bank pada pena dan kertas. Apakah Anda belajar dari contoh atau tutorial?
smuggledPancakes
1
Seperti yang saya katakan, pemetaan dari alamat ke bank relatif sederhana, jadi tidak sulit untuk mengetahui akses mana yang menuju ke bank mana dan oleh karena itu jika ada konflik bank. Makalah ini hanya untuk lebih banyak pola akses konflik, di mana saya tidak dapat melakukannya tanpanya.
Grizzly
13

Memori bersama yang dapat diakses secara paralel dibagi menjadi beberapa modul (disebut juga bank). Jika dua lokasi memori (alamat) terjadi di bank yang sama, maka Anda mendapatkan konflik bank selama akses dilakukan secara serial, kehilangan keuntungan dari akses paralel.

Belwood
sumber
Jadi apakah ini terkait dengan saat half-warp ingin menyimpan atau memuat memori? 16 utas akan mencoba melakukan transaksi memori dan dengan demikian mengakses bank yang sama dengan lebih dari satu utas menyebabkan pemrosesan serial? Juga, bagaimana cara memastikan Anda tidak menyimpan / memuat data di bank yang sama?
smuggledPancakes
10

Dengan kata sederhana, konflik bank adalah kasus ketika pola akses memori gagal mendistribusikan IO ke seluruh bank yang tersedia dalam sistem memori. Contoh berikut menjelaskan konsep tersebut: -

Misalkan kita memiliki array dua dimensi 512x512 bilangan bulat dan DRAM atau sistem memori kita memiliki 512 bank di dalamnya. Secara default, data array akan diatur sedemikian rupa sehingga arr [0] [0] pergi ke bank 0, arr [0] [1] pergi ke bank 1, arr [0] [2] ke bank 2 .... arr [0] [511] pergi ke bank 511. Untuk menggeneralisasi arr [x] [y] menempati nomor bank y. Sekarang beberapa kode (seperti yang ditunjukkan di bawah) mulai mengakses data di kolom mode utama yaitu. mengubah x sambil menjaga y konstan, maka hasil akhirnya adalah semua akses memori yang berurutan akan mencapai bank yang sama - maka bank konflik.

int arr[512][512];
  for ( j = 0; j < 512; j++ ) // outer loop
    for ( i = 0; i < 512; i++ ) // inner loop
       arr[i][j] = 2 * arr[i][j]; // column major processing

Masalah seperti itu, biasanya, dihindari oleh kompiler dengan melakukan buffering pada array atau menggunakan bilangan prima elemen dalam array.

Nitin Kunal
sumber
7

(CUDA Bank Conflict) Saya harap ini akan membantu .. ini penjelasan yang sangat bagus ...

http://www.youtube.com/watch?v=CZgM3DEBplE

Prashant M.
sumber
1
Perhatikan bahwa jawaban link-only tidak disarankan, jawaban SO harus menjadi titik akhir dari pencarian solusi (vs. referensi lain yang berhenti, yang cenderung menjadi basi seiring waktu). Harap pertimbangkan untuk menambahkan sinopsis yang berdiri sendiri di sini, dengan menyimpan tautan sebagai referensi.
kleopatra
Harap uraikan tautan dalam upaya untuk lebih membantu OP.
Peter Foti
1
Video ini sangat membantu! Dan saya tidak tahu mengapa memilih down! Ini adalah masukan yang sangat bagus! +1
Gabriel