Os coletores de lixo geracionais são inerentemente compatíveis com o cache?

38

Um coletor de lixo geracional típico mantém os dados alocados recentemente em uma região de memória separada. Em programas típicos, muitos dados são de curta duração; portanto, coletar lixo jovem (um ciclo menor do GC) com frequência e coletar lixo antigo com pouca frequência é um bom compromisso entre a sobrecarga de memória e o tempo gasto no GC.

Intuitivamente, o benefício de um coletor de lixo geracional em comparação com um coletor de região única deve aumentar à medida que a taxa de latência da memória principal em relação ao cache aumenta, porque os dados na região jovem são acessados ​​com frequência e mantidos em um único local. Os resultados experimentais corroboram essa intuição?

Gilles 'SO- parar de ser mau'
fonte
uma meta-discussão relacionada sobre as tags apropriadas para a pergunta.
Kaveh 26/03

Respostas:

19

Aqui estão alguns documentos que falam sobre as implicações de cache dos coletores de lixo geracionais:

Pelo que pude entender, a questão principal é que os sistemas de coleta de lixo trocam espaço na memória para evitar a coleta antecipada. O mesmo se aplica à memória cache. Como você sugeriu, as coisas da primeira geração provavelmente ficarão em cache e, portanto, sua alocação e coleta serão muito mais rápidas do que algo na memória principal ou paginadas em disco. O principal problema é o tamanho da primeira geração em relação ao tamanho do seu cache. Se o cache ficar cheio antes da primeira geração, você começará a perder esses benefícios à medida que as falhas começarem a se acumular.

Matt Balkam
fonte
10

Há um aspecto muito complicado de todos os coletores de lixo que pode ser encoberto em algumas descrições, e é a "verificação completa" ou "coleta completa". Periodicamente, aleatoriamente, intermitentemente, eles devem verificar todos os objetos. coletores geracionais são melhores em adiar a varredura completa e minimizar sua duração, mas ainda é necessário.

O coletor de gerações se concentrará no que às vezes é chamado de espaço "berçário", mas eventualmente / inevitavelmente terá que se reunir no espaço "mais antigo" da geração, causando uma verificação completa da memória.

Essa varredura completa é incompatível com quase todos os esquemas de cache de memória e (especialmente!) De virtualização, no sentido de que quase todos os esquemas de cache / virtualização de memória falharão / devem falhar gravemente em qualquer melhoria de desempenho nesse caso.

Portanto, a resposta principal para essa pergunta é com que freqüência a verificação completa é acionada e qual o efeito "ruim" quando ocorre e se pode ser tolerado. isso se resume a uma propriedade / questão mais dependente do aplicativo.

Em outras palavras, para "a maior parte" da operação do coletor, um cache provavelmente o ajudará (o cache e o espaço "jovem" geralmente se sobrepõem!), Mas há um período periódico, intermitente, eventual, inevitável, pesado, talvez até um pico "maciço" [degradante] de desempenho quando o espaço da "velha geração" seja totalmente coletado e a "taxa de acertos" do cache se degradará em muito ruim, pois muitos objetos fora dele são todos buscados em um loop restrito ciclo de varredura / coleta. Em outras palavras, uma descontinuidade periódica inevitável (onde estimativas / médias / tendências estatísticas de desempenho etc. são enganosas e inaplicáveis).

O que está surgindo agora são alguns novos sistemas de coleta projetados para serem combinados com os sistemas de gerenciamento de memória subjacentes (armazenamento em cache / virtualização). parece que as abordagens históricas que dissociam completamente os sistemas separados de coleta de memória, armazenamento em cache e virtualização não terão um desempenho tão bom quanto as abordagens que combinam / integram / abordam os três aspectos juntos.

Veja, por exemplo, coleta de lixo com reconhecimento de cache por Zhou e Demsky.

vzn
fonte
Então, você poderia argumentar que os GCs geracionais são compatíveis com o cache em comparação com os não-geracionais (clássicos)?
Raphael
Eu argumentaria que o GC deveria ser projetado de maneira integrada com caches e memória virtual como parte de seu design, o que é complicado nas arquiteturas existentes. no entanto, para expandir a resposta - sim, coletores geracionais agregam / consolodam / agrupam os objetos freqüentemente usados ​​na memória contígua, que são inerentemente mais compatíveis com o cache do que outros designs nos quais os objetos usados ​​com frequência e com pouca frequência são dispersos / misturados (embora os últimos ainda terá algum benefício de cache).
vzn
11
Um aspecto um tanto complicado da fusão de arquiteturas de GC e de armazenamento em cache / virtualização é que essas arquiteturas geralmente não se importam com o conteúdo das páginas de memória, mas em um sistema de GC elas precisam. Às vezes, idiomas diferentes prometem diferentes recursos relacionados ao GC para os programadores, e pode ser difícil descobrir quais recursos dar suporte no nível do sistema operacional. A melhor abordagem provavelmente diria que cada objeto precisa conter um ponteiro para uma estrutura cujos campos iniciais são definidos pelo sistema operacional, mas que podem ser seguidos por dados específicos do idioma que o sistema operacional não conheceria nem se importaria.
precisa