O que é um conflito bancário? (Fazendo programação CUDA/OpenCL)
-
27-09-2019 - |
Pergunta
Eu tenho lido o guia de programação para CUDA e OpenCL e não consigo descobrir o que é um conflito bancário. Eles meio que mergulham em como resolver o problema sem elaborar o próprio assunto. Alguém pode me ajudar a entender isso? Não tenho preferência se a ajuda estiver no contexto de CUDA/OpenCL ou apenas conflitos bancários em geral em ciência da computação.
Solução
Para NVIDIA (e AMD), GPUs, a memória local é dividida em bancos de memória. Cada banco pode abordar apenas um conjunto de dados por vez; portanto, se um Halfwarp tentar carregar/armazenar dados de/para o mesmo banco, o acesso deve ser serializado (este é um conflito bancário). Para GT200 GPUs, existem 16 bancos (32banks para Fermi), 16 ou 32 bancos para GPUs AMD (57xx ou superior: 32, tudo abaixo: 16)), que são intercalados com uma granuidade de 32 bits (então byte 0-3 estão em Banco 1, 4-7 no Banco 2, ..., 64-69 no Banco 1 e assim por diante). Para uma melhor visualização, basicamente se parece com o seguinte:
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 |...
...
Portanto, se cada segmento em um Halfwarp acessar valores sucessivos de 32 bits, não houver conflitos bancários. Uma exceção desta regra (cada thread deve acessar seu próprio banco) são transmissões: se todos os threads acessarem o mesmo endereço, o valor é lido apenas uma vez e transmitido a todos os threads (para GT200, deve ser todos os threads no meio -dia que acessam o O mesmo endereço, IIRC Fermi e AMD GPUs podem fazer isso para qualquer número de threads acessando o mesmo valor).
Outras dicas
A memória compartilhada que pode ser acessada em paralelo é dividida em módulos (também chamados de bancos). Se dois locais de memória (endereços) ocorrem no mesmo banco, você obterá um conflito bancário Durante o qual o acesso é feito em série, perdendo as vantagens do acesso paralelo.
Em palavras simples, o conflito bancário é um caso quando qualquer padrão de acesso à memória falha em distribuir IO nos bancos disponíveis no sistema de memória. Os seguintes exemplos elaboram o conceito:-
Suponhamos que tenhamos uma matriz bidimensional de 512x512 de números inteiros e nosso sistema de DRAM ou memória possui 512 bancos. Por padrão, os dados da matriz serão layout de uma maneira que o ARR [0] [0] vai para o Banco 0, arr [0] [1] vai para o Banco 1, arr [0] [2] para o Banco 2 .... ARR [0] [511] vai para o Banco 511. Para generalizar o ARR [x] [y] ocupa o número do banco y. Agora, algum código (como mostrado abaixo) começa a acessar dados na coluna principal de moda, ou seja. Alteração do X, mantendo Y constante, o resultado final será que todo o acesso consecutivo na memória atingirá o mesmo banco-daí o conflito bancário.
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
Tais problemas, geralmente, são evitados pelos compiladores, bufferndo a matriz ou usando o número principal de elementos na matriz.
(Conflito bancário CUDA) Espero que isso ajude .. isso é uma explicação muito boa ...
http://en.wikipedia.org/wiki/memory_bank
ehttp://mprc.pku.cn/mentors/training/iscareading/1989/p380-weiss/p380-weiss.pdf
Nesta página, você pode encontrar os detalhes sobre o banco de memória. Mas é um pouco diferente do que é dito @Grizzly. Nesta página, o banco é assim
Banco 1 2 3
Endereço | 0, 3, 6 ... | | 1, 4, 7 ... | | 2, 5,8 ... |
Espero que isso ajude