nvidia - Cos'è un conflitto bancario?(Fare programmazione CUDA / OpenCL)




bank-conflict (5)

La memoria condivisa a cui è possibile 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.

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



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


Sospetto che ci sia qualche problema con OpenCL negli ultimi driver NVidia su alcune schede video. Here e here sono alcuni rapporti su quelli. Prova a ripetere il test su GPU da un'altra famiglia.





cuda opencl nvidia bank-conflict