Espero que eles não tenham dito explicitamente exatamente "um programa que consiste apenas de átomos é livre de raça no SC-DRF". Isso está incorreto.
Eles dizem que "[na sincronização com escopo definido ... é possível escrever um programa de corrida que seja composto inteiramente de átomos se esses átomos não usarem os escopos corretamente" "[topo da página 2], que é um pouco diferente (e usa a palavra "racial" de forma ambígua, talvez levando você a acreditar que significava a afirmação incorreta.) Eles talvez devessem ter dito que, na sincronização de escopo, é possível escrever um programa não sequencialmente consistente que é composto inteiramente de atômica se esses atômicos não use escopos corretamente.
O SC-DRF (aproximadamente: a semântica de memória para C ++ e Java) divide os locais de memória em duas classes, objetos de sincronização (às vezes chamados atomics
) e objetos de dados . Na maioria das vezes, todas as operações em objetos de sincronização são garantidas como consistentes em sequência . [1] ( Não é livre de corrida.) Essa é uma restrição no compilador, não no programador. Ele diz que se o programador diz que um thread escreve objeto atômico, em a
seguida, escreve objeto atômico b
, todosos threads verão as gravações ocorrerem nesta ordem. (O compilador não tem permissão para reordenar os acessos e é necessário inserir as barreiras e cercas de memória apropriadas em máquinas que não são sequencialmente consistentes.)
Sequencialmente consistente significa que todos os threads em todos os processadores concordam com uma ordem total de todas as operações de memória. Se um thread pensa que a operaçãox aconteceu antes da operaçãoy, todos os threads pensam que a operaçãox aconteceu antes da operaçãoy. Sequencialmente consistente não significa não racial e nem determinístico . Por exemplo, dois segmentos diferentes podem tentar escrever a mesma variável de sincronização aproximadamente ao mesmo tempo. Esses acessos serão rápidos. Um sistema sequencialmente consistente apenas garante que, se um thread pensa que escrevex aconteceu antes de escrever y, todos os tópicos concordarão que escreverx aconteceu antes de escrever y. A consistência sequencial é útil porque você pode usá-la para construir e raciocinar sobre objetos úteis de sincronização não determinística, como mutexes e variáveis de condição.
O SC-DRF diz que, se o seu programa estiver livre de corrida de dados , as operações nos objetos de dados parecerão ser sequencialmente consistentes . É permitido ao compilador reordenar (ou às vezes eliminar) operações em objetos de dados e, se a máquina subjacente não for sequencialmente consistente, o compilador não precisará inserir barreiras ou cercas de memória. Mas o compilador não tem permissão para reordenar operações em objetos de dados com relação a operações em objetos de sincronização.
Dados livres de corrida não são iguais a corrida livre . E sequencialmente consistente não é o mesmo que sem raça . Um agendamento de execução de programa específico é livre de corrida de dados se, para qualquer par de objetos de dados,x e y, por dois threads diferentes (pelo menos um dos quais é uma operação de gravação), podemos usar a ordem (sequencialmente consistente) de acessos a objetos atômicos para provar que x aconteceu antes y ou y aconteceu antes x. Se não pudermos fazer a prova, o cronograma de execução é de dados corridos .
Um programa é livre de corrida de dados se todos os agendamentos de execução possíveis forem livres de corrida de dados. Um programa é com dados corridos se houver um agendamento de execução com dados corretos.
Ser livre de corrida de dados é uma restrição para o programador, não para o compilador. Ele diz que, se o seu programa possui dados de alta velocidade, ele não possui semântica. O compilador pode fazer o que quiser, incluindo interromper o programa, entrar em um loop infinito ou explodir o computador.
Oh céus. TL; DR! Ainda nem mencionei o SC-for-HRC!
No SC-for-HRC, os atômicos precisam especificar a qual escopo eles pertencem. Os acessos atômicos são garantidos (pelo compilador) para serem sequencialmente consistentes apenas dentro de seu próprio escopo. Todos os encadeamentos dentro do escopo concordam com a ordem em que os acessos atômicos ocorrem, mas os encadeamentos em um escopo diferente podem não concordar (e talvez nem consigam ver os acessos, muito menos a ordem deles).
Por exemplo, pode ser que todos os threads da GPU concordem que o thread 19 adquiriu o mutex A e depois o mutex B, mas todos os threads da CPU não concordam (ou sabem) que o thread 19 adquiriu o mutex A ou mutex B. O SC-DRF não possui "escopos", portanto não sofre esse problema.
[1] As exceções para os átomos sequencialmente consistentes têm a ver com o uso explícito std::memory_order_relaxed
. Então não faça isso. (E ignorarei as exceções no restante do que estou dizendo.)