Compartir a través de


Rendimiento en controladores de red

Minimizar la longitud de la trayectoria de envío y recepción

Aunque las rutas de acceso de envío y recepción difieren entre controladores, hay algunas reglas generales para las optimizaciones de rendimiento.

  • Optimice las rutas comunes. La herramienta Kernprof.exe se proporciona con las compilaciones de desarrollador e IDW de Windows y extrae la información necesaria. El desarrollador debe examinar las rutinas que consumen la mayoría de los ciclos de CPU e intentar reducir la frecuencia de estas rutinas a las que se llama o el tiempo invertido en estas rutinas.

  • Reduzca el tiempo invertido en DPC para que el controlador del adaptador de red no use recursos excesivos del sistema, lo que provocaría que el rendimiento general del sistema sufra.

  • Asegúrese de que el código de depuración no se compile en la versión final publicada del controlador; esto evita ejecutar código excesivo.

Creación de particiones de datos y código para minimizar el uso compartido entre procesadores

La creación de particiones es necesaria para minimizar los datos compartidos y el código entre procesadores. La creación de particiones ayuda a reducir el uso del bus del sistema y mejora la eficacia de la memoria caché del procesador. Para minimizar el uso compartido, los desarrolladores de controladores deben tener en cuenta lo siguiente:

  • Implemente el controlador como miniporte deserializado como se describe en Controladores de miniporte NDIS deserializado.

  • Use estructuras de datos por procesador para reducir el acceso a datos globales y compartidos. Esto le permite mantener contadores estadísticos sin sincronización, lo que reduce la longitud de la ruta de acceso del código y aumenta el rendimiento. Para las estadísticas críticas, utilice contadores por procesador que se sumen en el momento de la consulta. Si debe tener un contador global, use operaciones interbloqueadas en lugar de bloqueos de espera activa para manipular el contador. Consulte "Uso correcto de mecanismos de bloqueo" a continuación para obtener información sobre cómo evitar el uso de barreras activas.

    Para facilitar esto, se puede usar KeGetCurrentProcessorNumberEx para determinar el procesador actual. Para determinar el número de procesadores al asignar estructuras de datos por procesador, se puede usar KeQueryGroupAffinity .

    El número total de bits establecidos en la máscara de afinidad indica el número de procesadores activos en el sistema. Los controladores no deben suponer que todos los bits establecidos en la máscara serán contiguos porque es posible que los procesadores no estén numerados consecutivamente en las futuras versiones del sistema operativo. El número de procesadores de una máquina SMP es un valor de base cero.

    Si el controlador mantiene los datos por procesador, puede usar la función KeQueryGroupAffinity para reducir la contención de la línea de caché.

Evitar el uso compartido falso

El uso compartido falso se produce cuando los procesadores solicitan variables compartidas independientes entre sí. Sin embargo, dado que las variables están en la misma línea de caché, se comparten entre los procesadores. En tales situaciones, la línea de caché se desplazará de vuelta y vuelta entre los procesadores para cada acceso a cualquiera de las variables de ella, lo que provocará un aumento en los vaciados de caché y las recargas. Esto aumenta el uso del bus del sistema y reduce el rendimiento general del sistema.

Para evitar el uso compartido falso, alinee estructuras de datos importantes (como bloqueos de giro, encabezados de cola de búfer, listas enlazadas simples) a los límites de la línea de caché mediante NdisGetSharedDataAlignment.

Uso de mecanismos de bloqueo correctamente

Los bloqueos de giro pueden reducir el rendimiento si no se utilizan correctamente. Los controladores deben minimizar el uso de bloqueos de giro mediante operaciones interbloqueadas siempre que sea posible. Sin embargo, en algunos casos, un bloqueo de giro puede ser la mejor opción para algunos propósitos. Por ejemplo, si un controlador adquiere un bloqueo de giro mientras controla el recuento de referencias para el número de paquetes que no se han indicado de vuelta al controlador, no es necesario usar una operación interbloqueada. Para obtener más información, vea sincronización y notificación en controladores de red.

Estas son algunas sugerencias para usar mecanismos de bloqueo de forma eficaz:

Uso de DMA de 64 bits

DMA de 64 bits Si el adaptador de red admite DMA de 64 bits, se deben realizar pasos para evitar copias adicionales para direcciones por encima del intervalo de 4 GB. Cuando el controlador llama a NdisMRegisterScatterGatherDma, el indicador NDIS_SG_DMA_64_BIT_ADDRESS debe estar configurado en el parámetro Flags.

Garantizar la alineación adecuada del búfer

La alineación del búfer en un límite de línea de caché mejora el rendimiento al copiar datos de un búfer a otro. La mayoría de los búferes de recepción del adaptador de red se alinean correctamente cuando se asignan por primera vez, pero los datos de usuario que deben copiarse en el búfer de la aplicación quedan desalineados debido al espacio ocupado por el encabezado. En el caso de los datos TCP (el escenario más común), el cambio debido a los encabezados TCP, IP y Ethernet da como resultado un desplazamiento de 0x36 bytes. Para resolver este problema, se recomienda que los controladores asignen un búfer ligeramente mayor e inserten datos de paquetes en un desplazamiento de 0xA bytes. Esto garantizará que, después de que los búferes se desplacen 0x36 bytes en función del encabezado, los datos del usuario se alineen correctamente. Para obtener más información sobre los límites de la línea de caché, vea la sección Comentarios de NdisMAllocateSharedMemory.

Uso de Scatter-Gather DMA

Dispersión/Recolección de NDIS DMA proporciona al hardware compatibilidad con la transferencia de datos hacia y desde intervalos no contiguos de memoria física. Scatter-Gather DMA utiliza una estructura SCATTER_GATHER_LIST, que incluye un array de estructuras SCATTER_GATHER_ELEMENT y el número de elementos en el array. Esta estructura se recupera del descriptor de paquete que se pasa a la función de envío del controlador. Cada elemento de la matriz proporciona la longitud y la dirección física inicial de una región de Scatter-Gather físicamente contigua. El controlador usa la información de longitud y dirección para transferir los datos.

El uso de las rutinas de Scatter-Gather para las operaciones DMA puede mejorar el uso de los recursos del sistema al no bloquear estos recursos estáticamente, como ocurriría si se usaran registros de mapa. Para obtener más información, consulte Dispersión de NDIS/Recopilación de DMA.

Si el adaptador de red admite la descarga de segmentación TCP (descarga de envío grande), el controlador tendrá que pasar el tamaño máximo del búfer que puede obtener de TCP/IP al parámetro MaximumPhysicalMapping dentro de la función NdisMRegisterScatterGatherDma . Esto garantizará que el controlador tenga suficientes registros de asignación para compilar la lista de Scatter-Gather y eliminar las posibles asignaciones de búferes y la copia. Para obtener más información, consulte estos temas:

Compatibilidad con el control de flujo del lado de recepción

Para minimizar las interrupciones durante la reproducción multimedia en aplicaciones multimedia, los controladores NDIS 6.20 y versiones posteriores deben admitir la limitación lateral de recepción (RST) en el procesamiento de interrupciones de recepción. Para obtener más información, consulte:

Limitación lateral de recepción en NDIS 6.20 "Rutas de acceso de código de envío y recepción" en resumen de los cambios necesarios para portar un controlador de miniporte a NDIS 6.20