O que é um conflito de banco? (Fazendo programação Cuda / OpenCL)

95

Tenho lido o guia de programação de CUDA e OpenCL e não consigo descobrir o que é um conflito de banco. Eles simplesmente mergulham em como resolver o problema sem entrar em detalhes sobre o assunto em si. Alguém pode me ajudar a entender isso? Não tenho preferência se a ajuda é no contexto de CUDA / OpenCL ou apenas conflitos bancários em geral em informática.

panquecas contrabandeadas
fonte

Respostas:

105

Para NVIDIA (e AMD), GPUS, a memória local é dividida em bancos de memória. Cada banco pode endereçar apenas um conjunto de dados por vez, portanto, se um halfwarp tentar carregar / armazenar dados de / para o mesmo banco, o acesso terá que ser serializado (este é um conflito de banco). Para gt200 gpus existem 16 bancos (32 bancos para fermi), 16 ou 32 bancos para AMD gpus (57xx ou superior: 32, tudo abaixo: 16)), que são intercalados com uma granuidade de 32 bits (portanto, o byte 0-3 está 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 isto:

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 thread em um halfwarp acessa valores sucessivos de 32 bits, não há conflitos de banco. Uma exceção a esta regra (cada thread deve acessar seu próprio banco) são os broadcasts: Se todos os threads acessam o mesmo endereço, o valor é lido apenas uma vez e transmitido a todos os threads (para GT200, tem que ser todos os threads no halfwarp acessando o mesmo endereço, iirc fermi e AMD gpus podem fazer isso para qualquer número de threads acessando o mesmo valor).

Grizzly
fonte
3
Obrigado pelo visual e pela explicação. Eu não sabia sobre broadcasts e isso me parece uma informação importante :) Como eu faria para verificar se minhas cargas e armazenamentos não causam conflitos de banco na memória compartilhada? Eu tenho que chegar ao código de montagem de alguma forma ou existem outras maneiras?
Panquecas contrabandeadas de
3
uma vez que a ocorrência de conflito de banco é algo que será determinado em tempo de execução (o que significa que o compilador não sabe sobre isso, afinal a maioria dos endereços são gerados em tempo de execução), obter a versão compilada não ajudaria muito. Normalmente faço isso à moda antiga, menaing pego papel e caneta e começo a pensar sobre o que meu código armazena onde. Afinal, as regras que regem a ocorrência de conflitos bancários não são tão complexas. Caso contrário, você pode usar o criador de perfil nvidia OpenCL (deve ser fornecido com o sdk, iirc). Acho que tem um contador para serializa warp.
Grizzly
1
Obrigado por apontar que o warp serializa. Um dos arquivos de texto leia-me que vem com o criador de perfil de computação disse o seguinte:
contrabandeadas
1
Ack, desculpe o comentário acima, por algum motivo não posso reeditá-lo. De qualquer forma, encontrei isso no leia-me do criador de perfil de computação, "warp_serialize: Número de warps de thread que serializam em conflitos de endereço para memória compartilhada ou constante." Isso é ótimo porque eu posso ver facilmente se há conflitos apenas observando a saída do criador de perfil. Como você descobre se há conflitos bancários na caneta e no papel. Você aprendeu com algum exemplo ou tutorial?
panquecas contrabandeadas em
1
Como eu disse, o mapeamento de endereços para bancos é relativamente simples, então não é tão difícil descobrir quais acessos vão para qual banco e, portanto, se há conflitos entre bancos. O artigo é apenas para mais padrões de acesso de conflito, onde não posso fazer isso sem.
Grizzly
13

A memória compartilhada que pode ser acessada em paralelo é dividida em módulos (também chamados de bancos). Se duas localizações de memória (endereços) ocorrerem no mesmo banco, você terá um conflito de banco durante o qual o acesso é feito em série, perdendo as vantagens do acesso paralelo.

Belwood
fonte
Então, isso está relacionado a quando um half-warp deseja armazenar ou carregar memória? 16 threads estarão tentando fazer uma transação de memória e, portanto, acessar o mesmo banco com mais de uma thread causa o processamento serializado? Além disso, como garantir que você não armazene / carregue dados no mesmo banco?
Panquecas contrabandeadas de
10

Em palavras simples, o conflito de banco é um caso em que qualquer padrão de acesso à memória falha em distribuir IO entre os bancos disponíveis no sistema de memória. Os exemplos a seguir elaboram o conceito: -

Vamos supor que temos um array bidimensional de 512x512 de inteiros e nosso DRAM ou sistema de memória tem 512 bancos nele. Por padrão, os dados da matriz serão dispostos de forma que arr [0] [0] vá para o banco 0, arr [0] [1] vá para o banco 1, arr [0] [2] para o banco 2 .... arr [0] [511] vai para o banco 511. Para generalizar arr [x] [y] ocupa o banco número y. Agora, algum código (como mostrado abaixo) começa a acessar os dados na forma da coluna principal, ou seja. alterando x enquanto mantém y constante, o resultado final será que todos os acessos consecutivos à memória atingirão o mesmo banco - portanto, conflito de banco.

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

Esses problemas, geralmente, são evitados pelos compiladores armazenando o array em buffer ou usando um número primo de elementos no array.

Nitin Kunal
fonte
7

(Conflito do banco CUDA) Espero que isso ajude .. esta é uma explicação muito boa ...

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

Prashant M.
fonte
1
Observe que as respostas somente com link são desencorajadas, as respostas do SO devem ser o ponto final de uma busca por uma solução (em vez de outra parada de referências, que tendem a ficar obsoletas com o tempo). Considere adicionar uma sinopse independente aqui, mantendo o link como uma referência.
kleopatra
Elabore no link em um esforço para melhor auxiliar o OP.
Peter Foti
1
Este vídeo é muito útil! E não sei porque o voto negativo! É uma entrada muito boa! +1
Gabriel