Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
- Minimizando o comprimento do caminho de envio e recebimento
- Particionamento de dados e código para minimizar o compartilhamento entre processadores
- Evitar falsas partilhas
- Utilizar corretamente os mecanismos de bloqueio
- Usando DMA de 64 bits
- Garantindo o alinhamento adequado do buffer
- Usando Scatter-Gather DMA
- Suporte ao acelerador lateral de recebimento
Minimizando o comprimento do caminho de envio e recebimento
Embora os caminhos de envio e recebimento sejam diferentes de driver para driver, existem algumas regras gerais para otimizações de desempenho:
Otimize para os caminhos comuns. A ferramenta Kernprof.exe é fornecida com as compilações de desenvolvimento e IDW do Windows que extraem as informações necessárias. O desenvolvedor deve olhar para as rotinas que consomem mais ciclos de CPU e tentar reduzir a frequência dessas rotinas sendo chamadas ou o tempo gasto nessas rotinas.
Reduza o tempo gasto no DPC para que o driver do adaptador de rede não use recursos excessivos do sistema, o que prejudicaria o desempenho geral do sistema.
Certifique-se de que o código de depuração não é compilado na versão final lançada do driver; Isso evita a execução de código em excesso.
Particionamento de dados e código para minimizar o compartilhamento entre processadores
O particionamento é necessário para minimizar dados e códigos compartilhados entre processadores. O particionamento ajuda a reduzir a utilização do barramento do sistema e melhora a eficácia do cache do processador. Para minimizar a partilha, os programadores de drivers devem considerar o seguinte:
Implemente o driver como miniporta desserializada, conforme descrito em Drivers de miniporta NDIS desserializados.
Use estruturas de dados por processador para reduzir o acesso global e compartilhado a dados. Isso permite que você mantenha contadores estatísticos sem sincronização, o que reduz o comprimento do caminho do código e aumenta o desempenho. Para estatísticas vitais, tenha contadores por processador que são somados no momento da consulta. Se você precisar ter um contador global, use operações intertravadas em vez de bloqueios de rotação para manipular o contador. Consulte Usando mecanismos de bloqueio corretamente abaixo para obter informações sobre como evitar o uso de bloqueios de rotação.
Para facilitar isso, KeGetCurrentProcessorNumberEx pode ser usado para determinar o processador atual. Para determinar o número de processadores ao alocar estruturas de dados por processador, KeQueryGroupAffinity pode ser usado.
O número total de bits definidos na máscara de afinidade indica o número de processadores ativos no sistema. Os drivers não devem assumir que todos os bits definidos na máscara serão contíguos porque os processadores podem não ser numerados consecutivamente nas versões futuras do sistema operacional. O número de processadores em uma máquina SMP é um valor baseado em zero.
Se o driver mantiver dados por processador, você poderá usar a função KeQueryGroupAffinity para reduzir a contenção da linha de cache.
Evitar falsas partilhas
O compartilhamento falso ocorre quando os processadores solicitam variáveis compartilhadas que são independentes umas das outras. No entanto, como as variáveis estão na mesma linha de cache, elas são compartilhadas entre os processadores. Nessas situações, a linha de cache viajará de um lado para o outro entre os processadores para cada acesso a qualquer uma das variáveis nela, causando um aumento nas liberações e recargas de cache. Isso aumenta a utilização do barramento do sistema e reduz o desempenho geral do sistema.
Para evitar compartilhamento falso, alinhe estruturas de dados importantes (como bloqueios de rotação, cabeçalhos de fila de buffer, listas vinculadas individualmente) aos limites da linha de cache usando NdisGetSharedDataAlignment.
Utilizar corretamente os mecanismos de bloqueio
Os bloqueios de rotação podem reduzir o desempenho se não forem usados corretamente. Os condutores devem minimizar a utilização de bloqueios rotativos utilizando operações interligadas sempre que possível. No entanto, em alguns casos, um bloqueio de rotação pode ser a melhor escolha para alguns fins. Por exemplo, se um driver adquire um bloqueio de rotação enquanto manipula a contagem de referência para o número de pacotes que não foram indicados de volta ao driver, não é necessário usar uma operação intertravada. Para obter mais informações, consulte Sincronização e Notificação em Drivers de Rede.
Aqui estão algumas dicas para usar mecanismos de bloqueio de forma eficaz:
Use funções de lista vinculadas exclusivamente ao NDIS, como as seguintes, para gerenciar pools de recursos:
Se você precisar usar bloqueios rotativos, use-os apenas para proteger dados, não código. Não use um cadeado para proteger todos os dados usados em caminhos comuns. Por exemplo, separe os dados usados nos caminhos de envio e recebimento em duas estruturas de dados para que, quando o caminho de envio precisar bloquear seus dados, o caminho de recebimento não seja afetado.
Se você estiver usando bloqueios de rotação e o caminho já estiver no nível DPC, use as funções NdisDprAcquireSpinLock e NdisDprReleaseSpinLock para evitar código extra ao adquirir e liberar os bloqueios.
Para minimizar o número de aquisições e liberações de bloqueio de rotação, use estas funções NDIS RWLock:
Usando DMA de 64 bits
DMA de 64 bits Se o adaptador de rede suportar DMA de 64 bits, devem ser tomadas medidas para evitar cópias adicionais para endereços acima do intervalo de 4 GB. Quando o driver chama NdisMRegisterScatterGatherDma, o sinalizador NDIS_SG_DMA_64_BIT_ADDRESS deve ser definido no parâmetro Flags.
Garantindo o alinhamento adequado do buffer
O alinhamento do buffer em um limite de linha de cache melhora o desempenho ao copiar dados de um buffer para outro. A maioria dos buffers de receção do adaptador de rede são alinhados corretamente quando são alocados pela primeira vez, mas os dados do utilizador que eventualmente devem ser copiados para o buffer da aplicação estão desalinhados devido ao espaço de cabeçalho consumido. No caso de dados TCP (o cenário mais comum), a mudança devido aos cabeçalhos TCP, IP e Ethernet resulta numa deslocação de 0x36 bytes. Para resolver este problema, recomendamos que os controladores aloquem um buffer um pouco maior e insiram os dados do pacote com um deslocamento de 0xA bytes. Isso garantirá que, depois que os buffers forem deslocados por 0x36 bytes para o cabeçalho, os dados do usuário estejam alinhados corretamente. Para obter mais informações sobre limites de linha de cache, consulte a seção Comentários para NdisMAllocateSharedMemory.
Usando Scatter-Gather DMA
O NDIS Scatter/Gather DMA fornece suporte ao hardware para transferir dados de e para intervalos não contíguos de memória física. Scatter-Gather DMA usa uma estrutura SCATTER_GATHER_LIST , que inclui uma matriz de estruturas SCATTER_GATHER_ELEMENT e o número de elementos na matriz. Essa estrutura é recuperada do descritor de pacotes passado para a função send do driver. Cada elemento da matriz fornece o comprimento e o endereço físico inicial de uma região Scatter-Gather fisicamente contígua. O motorista usa as informações de comprimento e endereço para transferir os dados.
O uso das rotinas de Scatter-Gather para operações DMA pode melhorar a utilização dos recursos do sistema, não bloqueando esses recursos estaticamente, como ocorreria se os registros de mapa fossem usados. Para obter mais informações, consulte NDIS Scatter/Gather DMA.
Se o adaptador de rede suportar TCP Segmentation Offload (Large Send Offload), o driver precisará passar o tamanho máximo do buffer que pode obter do TCP/IP para o parâmetro MaximumPhysicalMapping dentro da função NdisMRegisterScatterGatherDma . Isso garantirá que o driver tenha registos de mapa suficientes para construir a lista de Scatter-Gather e eliminar quaisquer possíveis alocações de buffers e cópias. Para obter mais informações, consulte estes tópicos:
- Determinando as capacidades de descarregamento de tarefas
- Descarregando a segmentação de grandes pacotes TCP
Suporte ao acelerador lateral de recebimento
Para minimizar as interrupções durante a reprodução de mídia em aplicativos multimídia, os drivers NDIS 6.20 e posteriores devem suportar o acelerador lateral de recebimento (RST) no processamento de interrupções de recebimento. Para obter mais informações, consulte:
Receber acelerador lateral no NDIS 6.20 "Enviar e receber caminhos de código" em resumo das alterações necessárias para portar um driver de miniporta para o NDIS 6.20