Quest-ce quun verrou de mémoire ?

Historiquement, tous les programmes informatiques étaient écrits de manière totalement séquentielle. C'est simple à lire, à écrire et à comprendre. Il est également simple à exécuter pour un ordinateur et nécessite un matériel relativement simple. Avec ce paradigme de conception, les deux seules façons d'augmenter les performances du système sont d'écrire un code plus efficace et d'augmenter la vitesse du processeur. Augmenter l'efficacité du code peut être possible, mais il s'agit généralement d'un processus complexe avec des résultats souvent limités.

Pendant des décennies, les performances ont pu être réduites en attendant de nouveaux processeurs plus efficaces. Comme décrit par la loi de Moore, les performances des processeurs doublent environ tous les deux à trois ans. Malheureusement, la plupart de ces gains de performances provenaient de l'utilisation de nœuds de fabrication de plus en plus petits. La technologie moderne a du mal à réduire la taille des nœuds au rythme historique, grâce à des difficultés matérielles à travailler à l'échelle du nanomètre.

Pour contourner ce problème, les architectes de processeurs modernes ont choisi d'ajouter plusieurs cœurs de processeur aux processeurs. Chaque cœur de processeur peut agir indépendamment sur une tâche différente. S'ils ne peuvent pas combiner le même problème, ils peuvent travailler sur deux problèmes simultanément. Ce changement architectural fondamental offre de nombreuses performances supplémentaires, mais il ne profite pas directement aux processus individuels, bien qu'il réduise les conflits de temps processeur.

Pour tirer parti des processeurs multicœurs, le code doit être écrit de manière multithread. Chaque thread peut ensuite être exécuté simultanément, en adaptant les performances en fonction du nombre de threads et de cœurs de processeur disponibles. Faire cela, cependant, se heurte à un nouveau défi, la «condition de concurrence».

Remarque : Certaines tâches ne peuvent pas être multithread, tandis que d'autres peuvent être massivement multithread. Les gains de performance possibles dépendent du travail effectué.

Conditions de course

Les logiciels multithread peuvent tirer parti de plusieurs cœurs. Des dangers rôdent dans ces eaux, prêts à piéger le programmeur inexpérimenté. Une condition de concurrence peut se produire lorsque deux threads différents interagissent avec le même bit de mémoire.

Un exemple simple pourrait être deux threads essayant de vérifier et d'incrémenter une variable simultanément. Disons que a=0 . Deux threads différents exécutent alors leurs fonctions et, à un moment donné, vérifient a et l'incrémentent de un. Généralement, vous vous attendez à ce que le résultat de deux threads ajoutant un à zéro soit deux. La plupart du temps, cela devrait être le cas. Vous pouvez obtenir un résultat différent si les deux threads utilisent cette fonctionnalité spécifique au bon moment.

Dans ce cas, le premier thread lit la valeur de a . Avant que le premier thread ne puisse incrémenter la valeur de a , le deuxième thread le lit. Maintenant, le premier thread ajoute un à zéro, mais le deuxième thread croit déjà que la valeur est zéro, ajoutant un à zéro. Le résultat est que la valeur finale de a est 1 et non 2.

Course au pire scénario

Bien que l'exemple ci-dessus puisse ne pas sembler particulièrement mauvais, il peut avoir des effets dramatiques. Et si la valeur de a sélectionne le mode de fonctionnement d'une machine ? Que se passe-t-il si des modes de fonctionnement spécifiques de cette machine peuvent être dangereux, voire mortels ?

Les conditions de course n'ont pas non plus besoin d'être aussi simples. Par exemple, il peut être possible qu'un thread lise une section de mémoire en même temps qu'un autre thread y écrit. Dans ce cas, le fil de lecture peut obtenir un mélange étrange des données d'avant et d'après. Disons que la vérification est une simple vérification vrai/faux.

Si la variable disait vrai au début de la lecture mais était en train d'être remplacée par le mot faux, le résultat de l'opération de lecture pourrait être quelque chose comme « trlse ». Ce n'est pas "vrai" ou "faux". Ne pas être l'une des deux options dans un choix binaire entraînerait presque certainement le plantage de l'application. Cette corruption de la mémoire peut entraîner de nombreux problèmes de sécurité, tels que le déni de service et l'élévation des privilèges.

Verrouiller la course

Savoir quels bits de mémoire dans un programme sont partagés entre différents threads est essentiel pour éviter une condition de concurrence. Rien ne doit être fait si une variable n'est jamais contrôlée et accessible que par un seul thread. Si deux threads ou plus peuvent accéder à une variable, vous devez vous assurer que toutes les opérations sur cet élément de mémoire sont terminées indépendamment les unes des autres.

Cette indépendance est obtenue grâce à une serrure. Dans le code d'un programme, il faut mettre un verrou lors de l'écriture d'une fonction qui opère sur une mémoire partagée. Ce verrou empêche les autres threads d'accéder à cette partie de la mémoire jusqu'à ce que le verrou soit relâché.

La serrure n'est pas la plus élégante des solutions. D'une part, il a des frais généraux de mémoire. Il peut également forcer un thread à se bloquer, en attendant qu'un verrou soit libéré. Selon la situation, le verrou peut ne pas être libéré pendant très longtemps ou ne pas être libéré du tout. Dans le pire des cas, le déverrouillage d'un verrou pourrait dépendre de quelque chose qui se passe dans un autre thread bloqué, conduisant à un blocage.

Il est essentiel d'optimiser l'utilisation des serrures. Vous pouvez contrôler la granularité du verrou. Par exemple, si vous modifiez des données dans un tableau, vous pouvez verrouiller le tableau entier ou verrouiller uniquement la ligne modifiée. Verrouiller toute la table serait un verrou de granularité grossière. Cela minimise la surcharge liée à l'implémentation d'un trop grand nombre de verrous, mais augmente le risque qu'un autre thread soit bloqué par le verrou. Verrouiller uniquement la ligne serait un verrou de granularité fine. Cela est beaucoup moins susceptible d'interférer avec d'autres threads, mais cela signifie que des verrous déchirés seront nécessaires, ce qui augmentera la surcharge totale.

Conclusion

Un verrou de mémoire est un outil de code utilisé pour garantir l'atomicité des opérations en mémoire dans un environnement multithread. En verrouillant une partie de la mémoire avant de l'utiliser, vous pouvez être sûr qu'aucun comportement inattendu ne peut se produire en raison d'une condition de concurrence. Les verrous de mémoire entraînent une surcharge de mémoire, mais peuvent également provoquer un blocage.

Le blocage est l'endroit où un autre thread tente d'opérer sur une mémoire verrouillée. Le fil reste là, bloqué jusqu'à ce que le verrou soit libéré. Cela peut causer des problèmes si la libération du verrou nécessite qu'un autre thread fasse quelque chose, car il peut être bloqué avant qu'il ne puisse terminer la condition préalable pour libérer le verrou le bloquant. Les verrous de mémoire peuvent être évités en écrivant des codes non bloquants. Cependant, cela peut être complexe et moins performant que d'utiliser des verrous. N'oubliez pas de laisser vos commentaires ci-dessous.



Leave a Comment

Comment cloner un disque dur

Comment cloner un disque dur

À l’ère numérique moderne, où les données constituent un atout précieux, le clonage d’un disque dur sous Windows peut être un processus crucial pour beaucoup. Ce guide complet

Comment réparer le pilote WUDFRd qui n’a pas pu se charger sous Windows 10 ?

Comment réparer le pilote WUDFRd qui n’a pas pu se charger sous Windows 10 ?

Êtes-vous confronté au message d'erreur lors du démarrage de votre ordinateur indiquant que le pilote WUDFRd n'a pas pu se charger sur votre ordinateur ?

Comment réparer le code derreur 0x0003 de NVIDIA GeForce Experience

Comment réparer le code derreur 0x0003 de NVIDIA GeForce Experience

Rencontrez-vous le code d’erreur 0x0003 de l’expérience NVIDIA GeForce sur votre bureau ? Si oui, lisez le blog pour savoir comment corriger cette erreur rapidement et facilement.

How to Use Auto Clicker for Chromebook

How to Use Auto Clicker for Chromebook

Today, were going to delve into a tool that can automate repetitive clicking tasks on your Chromebook: the Auto Clicker. This tool can save you time and

Comment supprimer un GPU dun PC Windows en 2023

Comment supprimer un GPU dun PC Windows en 2023

Avez-vous besoin de retirer le GPU de votre PC ? Rejoignez-moi pour expliquer comment supprimer un GPU de votre PC dans ce guide étape par étape.

Comment installer un SSD NVMe sur un ordinateur de bureau et un ordinateur portable

Comment installer un SSD NVMe sur un ordinateur de bureau et un ordinateur portable

Vous avez acheté un nouveau SSD NVMe M.2 mais vous ne savez pas comment l'installer ? Lisez la suite pour savoir comment installer un SSD NVMe sur un ordinateur portable ou un ordinateur de bureau.

Quest-ce quune bombe logique ?

Quest-ce quune bombe logique ?

Une bombe logique est un incident de sécurité où un attaquant met en place une action différée. Continuez à lire pour en savoir plus.

Quest-ce que Stuxnet ?

Quest-ce que Stuxnet ?

Stuxnet était un ver auto-propagé. Il s'agissait de la première utilisation d'une cyber-arme et du premier malware.

Quest-ce quun hacker éthique ?

Quest-ce quun hacker éthique ?

Un hacker éthique est un hacker qui agit dans les limites de la loi. Continuez à lire pour en savoir plus sur le sujet.

Quest-ce que le chiffrement symétrique ?

Quest-ce que le chiffrement symétrique ?

Il existe de nombreuses parties différentes de la cryptographie. Si vous souhaitez chiffrer certaines données, vous pouvez utiliser deux types d'algorithmes : symétrique