AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 76971964
Accepted
ajp
ajp
Asked: 2023-08-25 02:12:24 +0800 CST2023-08-25 02:12:24 +0800 CST 2023-08-25 02:12:24 +0800 CST

ideal para liberar atômicos de baixa contenção dos caches?

  • 772

Se eu tiver alguma variável atômica que

  • é acessado com relativa pouca frequência (baixa contenção)
  • é acessado de maneira uniforme e aleatória por threads/núcleos (ou seja, se o thread A grava na variável, com alta probabilidade de não ser A o próximo a acessar a variável)

então, quando A terminar suas gravações na variável, devo de alguma forma liberar explicitamente a variável do cache l1/l2/l3 do núcleo do thread A, de modo que quando algum outro thread B precisar acessar a variável algum tempo mais tarde, ele encontra uma linha de cache limpa na RAM, em vez de uma linha de cache suja pertencente a outro núcleo?

Algumas subquestões

  • acessar uma linha de cache limpa da RAM é mais rápido ou mais lento do que acessar uma linha de cache suja de outro núcleo? Presumo que o primeiro seja mais rápido aqui, mas talvez não seja?
  • em vez de ir até a RAM, seria suficiente liberar para o cache l3 compartilhado (e fora do l1/l2 por núcleo)?
  • se seria benéfico liberar/gravar a linha de cache na RAM (ou l3), como posso fazer isso?

Além disso, que documentação/etc devo ler que cobre esse tipo de informação?

multithreading
  • 1 1 respostas
  • 20 Views

1 respostas

  • Voted
  1. Best Answer
    Peter Cordes
    2023-08-25T04:14:38+08:002023-08-25T04:14:38+08:00

    TL: DR: em x86 você deseja cldemote. Provavelmente não vale a pena fazer outras coisas, especialmente se o seu tópico de escritor puder estar fazendo um trabalho útil após esta loja. Ou, se isso não acontecer, e o sistema operacional não tiver outro thread para executar neste núcleo, colocar o núcleo em suspensão profunda envolverá a CPU escrevendo de volta suas linhas de cache sujas antes de desligar seus caches privados.


    Eu esperaria que a leitura da RAM geralmente fosse mais lenta do que uma linha suja em outro núcleo, especialmente em um sistema de soquete único. (No sistema NUMA de vários soquetes, se um núcleo remoto tiver uma cópia suja de uma linha de cache apoiada por DRAM local, isso pode mudar as coisas ou, pelo menos, tornar a DRAM menos atrasada.)

    Se não existir uma instrução de write-back boa (e barata para o escritor), provavelmente é melhor não fazer nada do que ir longe demais.

    A latência da DRAM primeiro deve falhar em L3, depois uma mensagem dessa fatia L3 deve chegar a um controlador de memória pela interconexão (por exemplo, barramento de anel ou malha) e, em seguida, você deve aguardar a latência do comando DRAM no barramento de memória externo. E já pode haver algumas solicitações enfileiradas no controlador de memória que o seu aguarda. Então os dados precisam voltar ao núcleo que fez a carga.

    Uma linha suja em outro núcleo também envolve outra mensagem após a detecção de uma falha L3, mas para o núcleo que possui a linha. (As próprias tags L3 podem indicar isso, como nas CPUs Intel que usam L3 inclusivo por esse motivo. Caso contrário, um diretório separado atuando como um filtro de espionagem). Ele deve ser capaz de responder mais rápido que um controlador DRAM, pois basta ler os dados de seu rápido cache L2 ou L1d e enviá-los para a fatia L3. (E também diretamente ao núcleo que o queria?)


    O caso ideal é um acerto no cache de último nível (normalmente L3), que protege o tráfego de coerência. Então você deseja que a linha seja removida do cache L1d/L2 privado do último núcleo para gravá-la. (Ou pelo menos gravado de volta para L3 e rebaixado para o estado Compartilhado nesses caches privados, não Exclusivo/Modificado. Portanto, uma leitura do mesmo núcleo poderia atingir L1d, precisando apenas de tráfego fora do núcleo (e RFO = Read For Ownership) se ele escreve novamente.)

    Mas nem todos os ISAs têm instruções para fazer isso de forma barata (sem desacelerar muito o gravador) ou sem ir muito longe e forçar uma gravação na RAM. Uma instrução como x86 clwbque força uma gravação na RAM, mas deixa a linha limpa em L3 depois, pode valer a pena ser considerada em alguns casos de uso, mas desperdiça largura de banda da DRAM. (Mas observe que o Skylake é implementado clwbcomo clflushopt; somente no Ice Lake e posteriores ele realmente mantém os dados em cache e também grava na DRAM).

    Se não for acessado com frequência, às vezes ele será gravado de volta em L3 apenas a partir da atividade normal no último núcleo a ser gravado (por exemplo, loop em um array), antes que qualquer outro núcleo o leia ou grave. Isso é ótimo, e qualquer coisa que expulse à força até mesmo de L3 impedirá que isso aconteça. Se a linha for acessada com frequência suficiente para permanecer normalmente quente no cache L3, você não vai querer anular isso.

    Se o thread/núcleo do gravador não tiver mais nada para fazer após a gravação, você poderia imaginar acessar outras linhas de cache para tentar fazer com que a gravação importante fosse despejada pelo mecanismo pseudo-LRU normal, mas isso só valeria a pena se a carga a latência para o próximo leitor era tão importante que valia a pena perder muito tempo de CPU no thread de escrita e gerar tráfego de coerência extra para outras linhas de cache agora, para otimizar para esse tempo posterior em algum outro thread.


    Relacionado:

    • Existe alguma maneira de escrever código de comunicação direto de núcleo a núcleo para CPU Intel? - As CPUs são muito bem otimizadas para gravação em um núcleo e leitura em outro núcleo, porque esse é um padrão comum em código real.

    • A barreira de memória de hardware torna a visibilidade das operações atômicas mais rápida, além de fornecer as garantias necessárias? (ou seja, quando este núcleo é confirmado para L1d ou quando invalida outros caches, eles terão que solicitar este: não, isso não torna isso mais rápido diretamente e não vale a pena fazer isso.)

    • x86 MESI invalida problema de latência da linha de cache - propõe que um terceiro thread leia os dados compartilhados a cada milissegundo para extrair dados do último gravador, tornando mais eficiente para um thread de alta prioridade eventualmente lê-los.

    • Inibição de cache da CPU (bastante centrada em x86)


    Instruções sobre vários ISAs

    • Instrução RISC-V para gravar linha de cache suja no próximo nível de cache - não existe nenhuma para RISC-V, pelo menos não em 2020.

    • ARM/AArch64: Não sei, mas não ficaria surpreso se houvesse alguma coisa. Edições são bem-vindas.

    • Algum outro ISA com instruções interessantes de gerenciamento de cache?

    x86 - nada de bom até o recentecldemote

    • Armazenamentos NT: ignora o cache até L3 e despeja a linha à força, caso não estivesse anteriormente. Então isso é um desastre.

    • clflush/ clflushopt- estes são despejados até a DRAM, você não quer isso. ( O oposto da dica de pré-busca de cache tem alguns números de desempenho para liberar pequenas matrizes.)

    • clwb- isso grava totalmente na DRAM, mas deixa os dados armazenados em cache no Ice Lake e posteriormente. ( No Skylake/Cascade Lake, na verdade, ele funciona da mesma forma que clflushopt. Pelo menos funciona sem falhas, para que futuras bibliotecas de memória persistente possam usá-lo sem verificar o material da versão ISA.) E o commit para DRAM (possivelmente para um NV-DIMM) pode ser ordenado por sfence, então presumivelmente o núcleo tem que rastreá-lo até o fim, ocupando espaço em suas filas?

    • cldemoteem Tremont e Sapphire Rapids - projetado exatamente para este caso de uso : é uma dica de desempenho, como o oposto de uma pré-busca. Ele escreve de volta para L3. Ele é executado em nopCPUs que não o suportam, uma vez que eles escolheram intencionalmente uma codificação que as CPUs existentes já executavam como um NOP anteriormente não documentado.

      Indica ao hardware que a linha de cache que contém o endereço linear especificado com o operando de memória deve ser movida (“rebaixada”) do(s) cache(s) mais próximo(s) do núcleo do processador para um nível mais distante do núcleo do processador. Isto pode acelerar os acessos subsequentes à linha por outros núcleos no mesmo domínio de coerência, especialmente se a linha foi escrita pelo núcleo que a rebaixa. Mover a linha dessa maneira é uma otimização de desempenho, ou seja, é uma dica que não modifica o estado arquitetural. O hardware pode escolher qual nível na hierarquia de cache manterá a linha (por exemplo, L3 em designs de servidor típicos). O operando de origem é um local de memória de bytes.

    Ao contrário clwb, ele não tem comportamento garantido (apenas uma dica) e nenhum pedido de ordem. até mesmo instruções de cerca, apenas wrt. armazena na mesma linha de cache. Portanto, o núcleo não precisa rastrear a solicitação depois de enviar uma mensagem pela interconexão com os dados a serem gravados em L3 (e notificando que a cópia da linha desse núcleo não está limpa).

    • 1

relate perguntas

  • Rust: Itere em uma pasta e abra cada arquivo

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    destaque o código em HTML usando <font color="#xxx">

    • 2 respostas
  • Marko Smith

    Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}?

    • 1 respostas
  • Marko Smith

    Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)?

    • 2 respostas
  • Marko Smith

    Por que as compreensões de lista criam uma função internamente?

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 respostas
  • Marko Smith

    Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

    • 4 respostas
  • Marko Smith

    Por que o construtor de uma variável global não é chamado em uma biblioteca?

    • 1 respostas
  • Marko Smith

    Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto?

    • 1 respostas
  • Marko Smith

    Somente operações bit a bit para std::byte em C++ 17?

    • 1 respostas
  • Martin Hope
    fbrereto Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi Por que as compreensões de lista criam uma função internamente? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A formato fmt %H:%M:%S sem decimais 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python std::views::filter do C++20 não filtrando a visualização corretamente 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa Por que o construtor de uma variável global não é chamado em uma biblioteca? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev Por que os compiladores perdem a vetorização aqui? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan Somente operações bit a bit para std::byte em C++ 17? 2023-08-17 17:13:58 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve