2010-09-28 4 views
1

J'ai une situation où, dans une application multithread, de nombreux threads différents accèdent à un dictionnaire en même temps. Il semble que cela pourrait être un goulot d'étranglement, mais il n'est pas clair - un scénario plausible est que plusieurs threads peuvent essayer d'extraire la même valeur (notez, cependant, que la structure de données est fixe - aucun thread ne fait d'écriture, mais des dizaines pourrait être en train d'essayer de lire la même valeur). La question est, est-ce que plusieurs threads peuvent lire la même valeur simultanément, ou est-ce un à la fois? Si oui, y a-t-il une autre structure de données qui pourrait être utilisée?Les performances du dictionnaire .NET peuvent-elles être dégradées avec un accès multithread?

Répondre

2

Plusieurs threads ne devraient pas avoir de problème à lire la même valeur de mémoire. Il peut y avoir une petite attente au niveau du système d'exploitation ou du matériel alors que la mémoire est réellement accessible pour chaque thread, mais c'est minuscule dans la plupart des cas, et pas facile à contourner.

Ce qui a attiré mon attention sur votre description du problème, c'est que "des douzaines [de threads] pourraient essayer de lire la même valeur". Si vous avez des douzaines de threads actifs en même temps, le goulot d'étranglement est la gestion des threads. Comme tout, il y a une loi des rendements décroissants et des déséconomies d'échelle; Avec le matériel actuel, environ deux fois plus de threads actifs que d'unités d'exécution (cœurs, processeurs logiques HT, mais l'architecture gère l'exécution multithread), votre CPU passe plus de temps à planifier l'exécution des threads qu'à gérer les threads. les instructions filetées. Oui, votre gestionnaire de tâches peut afficher des centaines de threads en vol, mais la grande majorité d'entre eux "dorment", écoutent l'interaction de l'utilisateur ou attendent simplement (comme les fils d'interrogation). Je chercherais à réduire le nombre de threads à pas plus de deux par "unité d'exécution", et idéalement seulement un couple de plus que le nombre d'unités d'exécution (donc EUs ont un thread à "passer à" alors que le FSB est la lecture de la mémoire pour un autre thread). Cela réduira le temps système que votre ordinateur consacre à la gestion de tous ces threads.

0

Il peut, oui. Cela ne signifie pas nécessairement que cela va bien.

Si vous verrouillez le dictionnaire pour l'accès en lecture/écriture, il y aura des frais supplémentaires pour le verrouillage ... sans parler de la possibilité de verrous mortels.

Sans verrouillage, les performances ne doivent pas être dégradées.

0

Si vous ne faites aucun lock() -ing n'importe où autour de l'accès au Dictionary en question, je doute que cela pourrait être la source de votre problème. Si vous ne lisez que des valeurs et que vous n'écrivez jamais, il ne devrait pas être nécessaire de les verrouiller (bien que vous deviez également prendre en compte l'accès aux variables membres des éléments du dictionnaire).

Le verrouillage pourrait causer une certaine dégradation si vous aviez BEAUCOUP de threads qui se verrouillaient fréquemment, mais si c'était le cas, je pense que vous alliez rencontrer des problèmes de performance le long d'autres lignes. Aussi, bien sûr, si le verrouillage n'est pas correctement implémenté, vous pourriez avoir des blocages ou des verrouillages inutiles.

0

Si vous n'avez pas besoin de fournir de verrous, alors perf sera au pair ou mieux si plusieurs threads sont lus dans la collection. On pourrait inspecter l'implémentation du dictionnaire dans le réflecteur et voir s'il y a des endroits qui modifient l'état de la table de hachage. Je ne crois pas que ce sera un problème.