"Zero-cópia" descreve operações de computador nas quais a unidade de processamento central (CPU) não executa a tarefa de copiar dados de uma área da memória para outra ou nas quais cópias de dados desnecessárias são evitadas. Isso é frequentemente usado para economizar ciclos de unidade de processamento central (CPU) e largura de banda de memória em muitas tarefas demoradas , como ao transmitir um arquivo em alta velocidade em uma rede, etc., melhorando assim o desempenho de programas (processos) executados por um computador.[1][2][3][4]

Princípio editar

Técnicas de programação de zero-cópia podem ser usadas ao trocar dados dentro de um processo do espaço do usuário (ou seja, entre dois ou mais threads, etc.) e/ou entre dois ou mais processos e/ou quando os dados precisam ser acessados / copiados / movidos dentro do espaço do núcleo (kernel) ou entre um processo do espaço do usuário e partes do espaço do núcleo (kernel) dos sistemas operacionais (OS).

Normalmente, quando um processo do espaço do usuário precisa executar operações do sistema, como ler ou gravar dados de/para um dispositivo (ou seja, um disco, um(a) controlador(a) de interface de rede (NIC), etc.) por meio de suas interfaces de software de alto nível ou como mover dados de um dispositivo para outro, etc. , ele precisa executar uma ou mais chamadas de sistema que são executadas no espaço do núcleo (kernel) pelo sistema operacional.

Se os dados tiverem que ser copiados ou movidos da origem para o destino e ambos estiverem localizados dentro do espaço do núcleo (kernel) (ou seja, dois arquivos, um arquivo e uma placa de rede, etc.), as cópias de dados desnecessárias, do espaço do núcleo (kernel) para o espaço do usuário e do espaço do usuário para espaço do núcleo (kernel), podem ser evitadas usando chamadas de sistema especiais (zero-cópia), geralmente disponíveis nas versões mais recentes dos sistemas operacionais populares.

Versões de zero-cópia de elementos do sistema operacional, como drivers de dispositivos, sistemas de arquivos, pilhas de protocolos de rede, etc., aumentam consideravelmente o desempenho de determinados programas aplicativos (que se tornam processos quando executados) e utilizam os recursos do sistema com mais eficiência. O desempenho é aprimorado ao permitir que a unidade de processamento central (CPU) passe para outras tarefas enquanto as cópias / o processamento de dados prossegue(m) em paralelo em outra parte da máquina. Além disso, as operações de zero-cópia reduzem o número de trocas de contexto demoradas entre o espaço do usuário e o espaço do núcleo (kernel). Os recursos do sistema são utilizados de forma mais eficiente, pois usar uma unidade de processamento central (CPU) sofisticada para executar extensas operações de cópia de dados, que é uma tarefa relativamente simples, é um desperdício se outros componentes do sistema mais simples puderem fazer a cópia.

Como exemplo, ler um arquivo e enviá-lo pela rede da maneira tradicional requer 2 cópias de dados extras (1 para ler do núcleo (kernel) para o espaço do usuário + 1 para gravar do usuário para o espaço do núcleo (kernel)) e 4 trocas de contexto por ciclo de leitura/gravação . Essas cópias de dados extras usam a unidade de processamento central (CPU). O envio desse arquivo usando mmap de dados de arquivo e um ciclo de chamadas de gravação reduz as alternâncias de contexto para 2 por chamada de gravação e evita as 2 cópias de dados extras do usuário anteriores. O envio do mesmo arquivo via zero-cópia reduz as trocas de contexto para 2 por chamada de envio de arquivo (sendfile) e elimina todas as cópias de dados extras da unidade de processamento central (CPU) (no usuário e no espaço do núcleo (kernel)).[1][2][3][4]

Os protocolos de zero-cópia são especialmente importantes para redes de velocidade muito alta nas quais a capacidade de um link de rede se aproxima ou excede a capacidade de processamento da unidade de processamento central (CPU). Nesse caso, a unidade de processamento central (CPU) pode gastar quase todo o seu tempo copiando os dados transferidos e, assim, se tornar um gargalo que limita a taxa de comunicação abaixo da capacidade do link. Uma regra prática usada na indústria é que aproximadamente um ciclo de clock da unidade de processamento central (CPU) é necessário para processar um bit de dados de entrada.

Implementações de hardware editar

Uma implementação inicial foi o OS/360 da IBM, onde um programa pode instruir o subsistema de canal a ler blocos de dados de um arquivo ou dispositivo em um buffer e gravar em outro, a partir do mesmo buffer, sem mover os dados.

As técnicas para criar software de zero-cópia incluem o uso de cópia baseada em acesso direto à memória (DMA) e mapeamento de memória por meio de uma unidade de gerenciamento de memória (MMU). Esses recursos requerem suporte de hardware específico e geralmente envolvem requisitos específicos de alinhamento de memória.

Uma abordagem mais recente usada pela arquitetura de sistema heterogênea (HSA) facilita a passagem de ponteiros entre a unidade de processamento central (CPU) e a unidade de processamento gráfico (GPU) e também outros processadores. Isso requer um espaço de endereço unificado para a unidade de processamento central (CPU) e a unidade de processamento gráfico (GPU).[5][6]

Interfaces de programas editar

Vários sistemas operacionais suportam a zero-cópia de dados de usuário e conteúdo de arquivos por meio de interfaces de programação de aplicativos (APIs) específicas.

Aqui estão listadas apenas algumas chamadas de sistema / interfaces de programação de aplicativos (APIs) bem conhecidas disponíveis nos sistemas operacionais (OSs) mais populares.

O NetWare da Novell oferece suporte a uma forma de zero-cópia por meio de blocos de controle de eventos (ECBs).

O comando copy interno em algumas versões do DR-DOS desde 1992 também o inicia quando o COMMAND.COM detecta que os arquivos a serem copiados estão armazenados em um servidor de arquivos NetWare,[7] caso contrário, ele volta à cópia normal de arquivos. O comando move externo desde o DR DOS 6.0 (1991) e MS-DOS 6.0 (1993) executa internamente um rename (fazendo com que apenas as entradas do diretório sejam modificadas no sistema de arquivos em vez de copiar fisicamente os dados do arquivo) quando a origem e o destino são localizado no mesmo volume lógico.[8]

O núcleo (kernel) do Linux suporta zero-cópia por meio de várias chamadas de sistema, como:

  • sendfile, sendfile64;[9]
  • splice;[10]
  • tee;[11]
  • vmsplice;[12]
  • process_vm_readv;[13]
  • process_vm_writev;[14]
  • copy_file_range;[15]
  • soquetes brutos com mmap de pacotes [16] ou AF_XDP.

Algumas delas são especificadas em POSIX e, portanto, também estão presentes nos núcleos (kernels) da distribuição de software Berkeley (BSD) ou no executivo interativo avançado (AIX) da IBM, alguns são exclusivos da interface de programação de aplicativos (API) do núcleo (kernel) do Linux.

Os sistemas operacionais FreeBSD, NetBSD, OpenBSD, DragonFly BSD, etc. suportam zero-cópia através de pelo menos estas chamadas de sistema:

  • sendfile;[17]
  • write,[18] writev [19] + mmap [20] ao gravar dados em um soquete de rede.

O macOS deve suportar zero-cópia através da parte FreeBSD do núcleo (kernel) porque oferece as mesmas chamadas de sistema (e suas páginas de manual ainda são marcadas como BSD), como:

O Solaris da Oracle oferece suporte a zero-cópia através de, pelo menos, estas chamadas de sistema:

O Windows da Microsoft oferece suporte a zero-cópia por pelo menos esta chamada de sistema:

Os fluxos de entrada da Java podem suportar zero-cópia por meio do método transferTo() do java.nio.channels.FileChannel se o sistema operacional subjacente também suportar zero-cópia.[28]

Os protocolos de acesso remoto direto à memória (RDMA) dependem profundamente de técnicas de zero-cópia.

Ver também editar

Referências editar

  1. a b Stancevic, Dragan (1 de janeiro de 2003). «Zero-cópia I: perspectiva do modo do usuário». www.linuxjournal.com (em inglês). Consultado em 14 de outubro de 2021 
  2. a b Bröse, Eduard (1 de janeiro de 2012). «Zero-cópia: Técnicas, benefícios e armadilhas». citeseerx.ist.psu.edu (em inglês). CiteSeerX 10.1.1.93.9589 . Consultado em 14 de outubro de 2021 
  3. a b Song, Jia; Alves-Foss, Jim (1 de janeiro de 2012). «Revisão de desempenho das técnicas de zero-cópia» (PDF). www.uidaho.edu (em inglês). Consultado em 14 de outubro de 2021 
  4. a b Baldwin, John (1 de maio de 2020). «Transferência de TLS no núcleo (kernel (PDF). freebsdfoundation.org (em inglês). Consultado em 14 de outubro de 2021 
  5. «O guia do programador para a galáxia das unidades aceleradas de processamento (APU (PDF) 
  6. «AMD descreve roteiro da HSA: memória unificada para CPU/GPU». 2 de fevereiro de 2012 
  7. «Kit de fonte legível por máquina (M.R.S) do Caldera OpenDOS 7.01». Caldera, Inc. 1 de maio de 1997. Consultado em 2 de janeiro de 2022. Arquivado do original em 7 de agosto de 2021  [1] (Implementado desde o DR DOS "Panther" em 22/06/1992, consulte COMCPY.C/DOSIF.ASM nos fontes do COMMAND.COM do OpenDOS 7.01.)
  8. Paul, Matthias R. (30 de julho de 1997). «II.4. Propriedades não documentadas de comandos externos: MOVE.EXE». DICAS NWDOS — Dicas e truques sobre o Novell DOS 7, com vistas a detalhes não documentados, bugs e soluções alternativas. MPDOSTIP. Col: Release 157 (em alemão) 3 ed. [S.l.: s.n.] Consultado em 6 de agosto de 2014. Arquivado do original em 10 de setembro de 2017  (O NWDOSTIP.TXT é um trabalho abrangente sobre o DOS 7 da Novell e o OpenDOS 7.01, incluindo a descrição de muitos recursos internos e não documentados. Faz parte da, ainda maior, coleção MPDOSTIP.ZIP do autor mantida até 2001 e distribuída em muitos sites na época. O link fornecido aponta para uma versão mais antiga, convertida em HTML, do arquivo NWDOSTIP.TXT.) [2]
  9. «sendfile(2) - Página de manual do Linux». man7.org (em inglês). 22 de março de 2021. Consultado em 13 de outubro de 2021 
  10. «splice(2) - Página de manual do Linux». man7.org (em inglês). 22 de março de 2021. Consultado em 13 de outubro de 2021 
  11. «tee(2) - Página de manual do Linux». man7.org (em inglês). 22 de março de 2021. Consultado em 13 de outubro de 2021 
  12. «vmsplice(2) - Página de manual do Linux». man7.org (em inglês). 22 de março de 2021. Consultado em 13 de outubro de 2021 
  13. «process_vm_readv(2) - Página de manual do Linux». man7.org (em inglês). 22 de março de 2021. Consultado em 13 de outubro de 2021 
  14. «process_vm_writev(2) - Página de manual do Linux». man7.org (em inglês). 22 de março de 2021. Consultado em 13 de outubro de 2021 
  15. «copy_file_range(2) - Página de manual do Linux». man7.org (em inglês). 22 de março de 2021. Consultado em 13 de outubro de 2021 
  16. «Documentação do PACKET_MMAP do Linux». kernel.org 
  17. «sendfile(2) - Páginas de manual do FreeBSD». www.freebsd.org (em inglês). 30 de abril de 2020. Consultado em 13 de outubro de 2021 
  18. «write(2) - Páginas de manual do FreeBSD». www.freebsd.org (em inglês). 30 de abril de 2020. Consultado em 13 de outubro de 2021 
  19. «writev(2) - Páginas de manual do FreeBSD». www.freebsd.org (em inglês). 30 de abril de 2020. Consultado em 13 de outubro de 2021 
  20. «mmap(2) - Páginas de manual do FreeBSD». www.freebsd.org (em inglês). 30 de abril de 2020. Consultado em 13 de outubro de 2021 
  21. «sendfile(2) - Página de manual do mac OS X». developer.apple.com (em inglês). 31 de março de 2006. Consultado em 13 de outubro de 2021 
  22. «sendfile(3C) - Páginas de manual do Solaris». docs.oracle.com (em inglês). 13 de agosto de 2021. Consultado em 13 de outubro de 2021 
  23. «sendfilev(3C) - Páginas de manual do Solaris». docs.oracle.com (em inglês). 13 de agosto de 2021. Consultado em 13 de outubro de 2021 
  24. «write(2) - Páginas de manual do Solaris». docs.oracle.com (em inglês). 13 de agosto de 2021. Consultado em 13 de outubro de 2021 
  25. «writev(2) - Páginas de manual do Solaris». docs.oracle.com (em inglês). 13 de agosto de 2021. Consultado em 13 de outubro de 2021 
  26. «mmap(2) - Páginas de manual do Solaris». docs.oracle.com (em inglês). 13 de agosto de 2021. Consultado em 13 de outubro de 2021 
  27. «Função TransmitFile (Win32. docs.microsoft.com (em inglês). 10 de maio de 2021. Consultado em 13 de outubro de 2021 
  28. Palaniappan, Sathish K.; Nagaraja, Pramod B. (2 de setembro de 2008). «Zero-cópia Java». developer.ibm.com (em inglês). Consultado em 13 de outubro de 2021