Cos’è un conflitto bancario? (Fare programmazione CUDA / OpenCL)

Ho letto la guida alla programmazione per CUDA e OpenCL e non riesco a capire cos’è un conflitto bancario. Si sono semplicemente immersi nel modo di risolvere il problema senza approfondire l’argomento. Qualcuno può aiutarmi a capirlo? Non ho alcuna preferenza se l’aiuto è nel contesto di CUDA / OpenCL o solo in conflitti bancari in generale in informatica.

Per nvidia (e amd per quella materia) gpus la memoria locale è divisa in banchi di memoria. Ogni banca può indirizzare solo un set di dati alla volta, quindi se un halfwarp tenta di caricare / memorizzare dati da / verso la stessa banca l’accesso deve essere serializzato (questo è un conflitto bancario). Per gt200 gpus ci sono 16 banche (32 banche per fermi), 16 o 32 banche per AMD gpus (57xx o superiore: 32, tutto quanto segue: 16)), che sono intercalati con una granuità di 32 bit (quindi il byte 0-3 è in banca 1, 4-7 nella banca 2, …, 64-69 nella banca 1 e così via). Per una migliore visualizzazione sembra sostanzialmente questo:

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 |... ... 

Quindi se ogni thread in un halfwarp accede a successivi valori a 32 bit non ci sono conflitti bancari. Un’eccezione da questa regola (ogni thread deve accedere alla propria banca) sono trasmissioni: se tutti i thread accedono allo stesso indirizzo, il valore viene letto solo una volta e trasmesso a tutti i thread (per GT200 deve essere tutto il thread nel halfwarp che accede al lo stesso indirizzo, iirc fermi e AMD gpus possono farlo per qualsiasi numero di thread che accedono allo stesso valore).

La memoria condivisa a cui è ansible accedere in parallelo è divisa in moduli (chiamati anche banchi). Se nella stessa banca si verificano due posizioni (indirizzi) di memoria, si verifica un conflitto bancario durante il quale l’accesso viene eseguito in serie, perdendo i vantaggi dell’accesso parallelo.

In parole semplici, il conflitto bancario è un caso in cui un modello di accesso alla memoria non riesce a distribuire IO tra i banchi disponibili nel sistema di memoria. I seguenti esempi elabora il concetto: –

Supponiamo di avere un array di numeri interi 512×512 bidimensionali e il nostro sistema DRAM o di memoria contenga 512 banchi. Di default i dati dell’array saranno disposti in modo che arr [0] [0] passi al banco 0, arr [0] [1] passi al banco 1, arr [0] [2] al banco 2 …. arr [0] [511] va al banco 511. Per generalizzare arr [x] [y] occupa il numero di banco y. Ora un po ‘di codice (come mostrato di seguito) inizia ad accedere ai dati nella colonna major fashion ie. cambiando x mantenendo costante y, il risultato finale sarà che tutti gli accessi alla memoria consecutivi colpiranno lo stesso banco, quindi il conflitto bancario.

 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 

Tali problemi, di solito, vengono evitati dai compilatori mediante il buffering dell'array o l'utilizzo del numero primo di elementi nell'array.

(CUDA Bank Conflict) Spero che questo ti aiuti .. questa è una spiegazione molto buona …

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

http://en.wikipedia.org/wiki/Memory_bank
e http://mprc.pku.cn/mentors/training/ISCAreading/1989/p380-weiss/p380-weiss.pdf

da questa pagina, è ansible trovare i dettagli sul banco di memoria. ma è leggermente diverso da quello che viene detto da @Grizzly. in questa pagina, la banca è così

bank 1 2 3

indirizzo | 0, 3, 6 … | | 1, 4, 7 … | | 2, 5,8 … |

spero che questo possa aiutare