Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
- Réduction de la longueur du chemin d’accès d’envoi et de réception
- Partitionnement des données et du code pour réduire le partage entre les processeurs
- Éviter le partage faux
- Utilisation correcte des mécanismes de verrouillage
- Utilisation de DMA 64 bits
- Garantir l’alignement approprié de la mémoire tampon
- Utilisation de Scatter-Gather DMA
- Prise en charge de la limitation côté réception
Réduction de la longueur du chemin d’accès d’envoi et de réception
Bien que les chemins d’envoi et de réception diffèrent du pilote au pilote, il existe des règles générales pour les optimisations des performances :
Optimisez les chemins d’accès courants. L’outil Kernprof.exe est fourni avec les builds développeur et IDW de Windows qui extraient les informations nécessaires. Le développeur doit examiner les routines qui consomment le plus de cycles d’UC et tenter de réduire la fréquence de ces routines appelées ou le temps passé dans ces routines.
Réduisez le temps passé dans les DPC afin que le pilote de la carte réseau n’utilise pas de ressources système excessives, ce qui nuirait aux performances globales du système.
Assurez-vous que le code de débogage n’est pas compilé dans la version finale publiée du pilote ; cela évite d’exécuter un excès de code.
Partitionnement des données et du code pour réduire le partage entre les processeurs
Le partitionnement est nécessaire pour réduire les données partagées et le code entre les processeurs. Le partitionnement permet de réduire l’utilisation du bus système et d’améliorer l’efficacité du cache du processeur. Pour réduire le partage, les développeurs de pilotes doivent prendre en compte les éléments suivants :
Implémentez le pilote en tant que miniport désérialisé comme décrit dans Les pilotes miniport NDIS désérialisés.
Utilisez des structures de données par processeur pour réduire l’accès global et partagé aux données. Cela vous permet de conserver les compteurs statistiques sans synchronisation, ce qui réduit la longueur du chemin d’accès du code et augmente les performances. Pour les statistiques vitales, les compteurs par processeur sont ajoutés ensemble au moment de la requête. Si vous devez disposer d’un compteur global, utilisez des opérations interblocées au lieu de verrous de rotation pour manipuler le compteur. Consultez la section Utilisation correcte des mécanismes de verrouillage ci-dessous pour savoir comment éviter l’utilisation des verrous de rotation.
Pour faciliter cela, KeGetCurrentProcessorNumberEx peut être utilisé pour déterminer le processeur actuel. Pour déterminer le nombre de processeurs lors de l’allocation de structures de données par processeur, KeQueryGroupAffinity peut être utilisé.
Le nombre total de bits définis dans le masque d’affinité indique le nombre de processeurs actifs dans le système. Les pilotes ne doivent pas supposer que tous les bits définis dans le masque seront contigus, car les processeurs risquent de ne pas être numérotés consécutivement dans les futures versions du système d’exploitation. Le nombre de processeurs d’une machine SMP est une valeur de base zéro.
Si votre pilote gère les données par processeur, vous pouvez utiliser la fonction KeQueryGroupAffinity pour réduire la contention de ligne de cache.
Éviter le partage faux
Le partage faux se produit lorsque les processeurs demandent des variables partagées indépendantes les unes des autres. Toutefois, étant donné que les variables se trouvent sur la même ligne de cache, elles sont partagées entre les processeurs. Dans de telles situations, la ligne de cache se déplace de retour en arrière entre les processeurs pour chaque accès à l’une des variables qu’elle contient, ce qui entraîne une augmentation des vidages et rechargements du cache. Cela augmente l’utilisation du bus système et réduit les performances globales du système.
Pour éviter le faux partage, alignez les structures de données importantes (telles que les verrous de rotation, les en-têtes de file d’attente et les listes simplement chaînées) aux limites de ligne de cache à l’aide de NdisGetSharedDataAlignment.
Utilisation correcte des mécanismes de verrouillage
Les verrous de rotation peuvent réduire les performances s’ils ne sont pas utilisés correctement. Les pilotes doivent réduire leur utilisation des verrous de rotation à l’aide d’opérations interblocées dans la mesure du possible. Toutefois, dans certains cas, un verrou de rotation peut être le meilleur choix à certaines fins. Par exemple, si un pilote acquiert un spinlock lors de la gestion du compteur de références pour le nombre de paquets qui n'ont pas encore été renvoyés au pilote, il n'est pas nécessaire d'utiliser une opération interverrouillée. Pour plus d’informations, consultez synchronisation et notification dans les pilotes réseau.
Voici quelques conseils pour utiliser efficacement des mécanismes de verrouillage :
Utilisez des fonctions de liste liée à NDIS telles que les suivantes pour gérer les pools de ressources :
Si vous avez besoin d’utiliser des verrous de rotation, utilisez-les uniquement pour protéger les données, et non le code. N’utilisez pas de verrou pour protéger toutes les données utilisées dans les chemins d’accès courants. Par exemple, séparez les données utilisées dans les chemins d’accès d’envoi et de réception dans deux structures de données afin que lorsque le chemin d’accès d’envoi doit verrouiller ses données, le chemin de réception n’est pas affecté.
Si vous utilisez des verrous de rotation et que le chemin est déjà au niveau DPC, utilisez les fonctions NdisDprAcquireSpinLock et NdisDprReleaseSpinLock pour éviter tout code supplémentaire lors de l’acquisition et de la libération des verrous.
Pour réduire le nombre d'acquisitions et de libérations du verrou à bascule, utilisez ces fonctions NDIS RWLock :
Utilisation de DMA 64 bits
DMA 64 bits Si la carte réseau prend en charge la DMA 64 bits, les étapes doivent être effectuées pour éviter des copies supplémentaires pour les adresses au-dessus de la plage de 4 Go. Lorsque le pilote appelle NdisMRegisterScatterGatherDma, l’indicateur NDIS_SG_DMA_64_BIT_ADDRESS doit être défini dans le paramètre Flags .
Garantir l’alignement approprié de la mémoire tampon
L’alignement de la mémoire tampon sur une limite de ligne de cache améliore les performances lors de la copie de données d’une mémoire tampon vers une autre. La plupart des mémoires tampons de réception de la carte réseau sont correctement alignées lorsqu’elles sont allouées pour la première fois, mais les données utilisateur qui doivent éventuellement être copiées dans la mémoire tampon de l’application sont mal alignées en raison de l’espace d’en-tête consommé. Dans le cas des données TCP (le scénario le plus courant), le décalage dû aux en-têtes TCP, IP et Ethernet entraîne un décalage de 0x36 octets. Pour résoudre ce problème, nous recommandons aux pilotes d’allouer une mémoire tampon légèrement plus grande et d’insérer des données de paquets à un décalage de 0xA octets. Cela garantit que, une fois les buffers déplacés par 0x36 octets pour l’en-tête, les données utilisateur sont correctement alignées. Pour plus d’informations sur les limites de ligne de cache, consultez la section Remarques pour NdisMAllocateSharedMemory.
Utilisation de Scatter-Gather DMA
NDIS Scatter/Gather DMA offre au matériel la prise en charge du transfert de données vers et depuis des plages non contiguës de la mémoire physique. Scatter-Gather DMA utilise une structure SCATTER_GATHER_LIST , qui inclut un tableau de structures SCATTER_GATHER_ELEMENT et le nombre d’éléments du tableau. Cette structure est récupérée à partir du descripteur de paquets passé à la fonction d’envoi du pilote. Chaque élément du tableau fournit la longueur et l'adresse physique de départ d'une région Scatter-Gather physiquement contiguë. Le pilote utilise les informations de longueur et d’adresse pour transférer les données.
L’utilisation des routines de Scatter-Gather pour les opérations DMA peut améliorer l’utilisation des ressources système en ne verrouillant pas ces ressources de manière statique, comme cela se produit si des registres cartographiques ont été utilisés. Pour plus d’informations, consultez NDIS Scatter/Gather DMA.
Si l'adaptateur réseau prend en charge la fonctionnalité de déchargement de segmentation TCP (Large Send Offload), le pilote devra transmettre la taille maximale de mémoire tampon qu'il peut obtenir à partir de TCP/IP au paramètre MaximumPhysicalMapping de la fonction NdisMRegisterScatterGatherDma. Cela garantit que le pilote dispose de suffisamment de registres de cartographie pour générer la liste Scatter-Gather et d’éliminer les éventuelles allocations de mémoire tampon et copies. Pour plus d’informations, consultez les rubriques suivantes :
- Détermination des fonctionnalités de déchargement des tâches
- Décharger la segmentation des gros paquets TCP
Prise en charge de la limitation de réception
Pour réduire les interruptions lors de la lecture multimédia dans les applications multimédias, les pilotes NDIS 6.20 et ultérieur doivent prendre en charge la limitation latérale de réception (RST) lors du traitement des interruptions de réception. Pour plus d’informations, consultez :
Limitation latérale de réception dans NDIS 6.20 « Chemins d’envoi et de réception de code » en résumé des modifications requises pour porter un pilote Miniport vers NDIS 6.20