2010-10-14 5 views
4

Nous devons rendre notre système hautement évolutif et il a été développé pour la plate-forme Windows en utilisant VC++. Dites d'abord, nous aimerions traiter 100 demandes (à partir de msmq) simultanément. Quelle serait la meilleure approche? Processus unique avec 100 threads ou 2 processus avec 50-50 threads? Quel est le gain en dehors de la mémoire de processus en cas de seconde approche. fait dans Windows premier temps CPU est alloué à traiter, puis divisé entre les threads pour ce processus, ou OS compte le nombre de threads pour chaque processus et allouer CPU sur la base de threads plutôt que de traiter. Nous remarquons que dans le premier cas, l'utilisation du processeur est de 15-25% et nous voulons consommer plus de CPU. Rappelez-vous que nous aimerions obtenir des performances optimales, donc 100 demandes sont juste par exemple. Nous avons également remarqué que si nous augmentons le nombre de threads du processus au-dessus de 120, les performances se dégradent en raison des changements de contexte.Windows, processus multiples vs threads multiples

Un autre point; notre produit supporte déjà le clustering, mais nous voulons utiliser plus de CPU sur le seul noeud.

Toutes les suggestions seront grandement appréciées.

Répondre

3

L'approche standard sur les fenêtres est de plusieurs threads. Ne pas dire que c'est toujours votre meilleure solution mais il y a un prix à payer pour chaque thread ou processus et sur Windows un processus est plus cher. En ce qui concerne l'ordonnanceur, je ne suis pas sûr mais vous pouvez définir le prieuré du processus et des discussions. Le véritable avantage pour les threads est leur espace d'adressage partagé et leur capacité à communiquer sans IPC, mais la synchronisation doit être soigneusement gérée.

Si votre système est déjà développé, ce qui semble être le cas, il est plus facile de mettre en œuvre une solution de processus multiples, surtout s'il y a une chance que plus d'une machine puisse être utilisée. Comme votre IPC de 2 processus sur une machine peut évoluer vers plusieurs machines dans le cas général. La plupart des tentatives de parallélisation massive échouent parce que le système entier n'est pas évalué pour les goulots d'étranglement. Par exemple, si vous implémentez 100 threads qui écrivent tous dans la même base de données, vous pouvez obtenir peu de performances réelles et attendre simplement votre base de données.

juste mes .02

+1

oui, nous l'avons fait face. base de données est le goulot d'étranglement majeur. de ne pas offenser qui que ce soit, mais nous avons eu de bien meilleures performances avec Oracle que le serveur SQL. mais ici dans notre région la plupart de nos clients collent avec sql server (étant moins cher), donc un vrai goulot d'étranglement pour nous. –

3

Vous processus cant plus de demandes que vous avez des noyaux CPU. Les solutions évolutives "rapides" impliquent la mise en place de pools de threads, où le nombre de threads actifs (non bloqués sur IO) == le nombre de cœurs de processeurs. Donc, la création de 100 threads parce que vous voulez traiter 100 demandes msmq n'est pas une bonne conception.

Windows dispose d'un mécanisme de pool de threads appelé IO Completion Ports. Avec les ports d'achèvement d'E/S, la conception est poussée vers un processus unique car, dans une conception multiprocessus, chaque processus dispose de son propre pool de threads IO Completion Port qu'il gèrerait de manière indépendante, ce qui augmenterait considérablement le nombre de threads. pour les cœurs de processeurs. L'idée principale d'un port d'achèvement d'E/S est qu'il s'agit d'une file d'attente en mode noyau: vous pouvez publier manuellement des événements dans la file d'attente ou obtenir automatiquement des compléments d'E/S asynchrones en associant un fichier (fichier, socket, pipe) poignées avec le port. D'un autre côté, le mécanisme de port d'achèvement IO supprime automatiquement les événements sur les threads de travail en attente - mais il ne supprime pas les jobs s'il détecte que les threads "actifs" actuels du pool de threads = le nombre de cœurs de processeurs. Utilisation des compléments d'E/S Les ports peuvent potentiellement augmenter considérablement l'évolutivité d'un service, mais le gain est généralement beaucoup plus faible que prévu car d'autres facteurs interviennent rapidement lorsque tous les cœurs de CPU sont en concurrence pour les autres services.Si vos services sont développés en C++, vous pouvez trouver que l'accès sérialisé au tas est une grosse performance moins - bien que la version 6.1 de Windows semble avoir implémenté un tas de contention faible, donc cela pourrait être moins un problème. En résumé, vos gains de performances les plus importants proviendraient théoriquement d'une conception utilisant des pools d'unités d'exécution gérés en un seul processus. Mais vous dépendez fortement des bibliothèques que vous utilisez pour ne pas sérialiser l'accès aux ressources critiques, ce qui peut rapidement vous faire perdre tous les gains de performance théoriques. Si le code de la bibliothèque est sérialisé (comme dans le cas de la création d'objets C++ & la destruction étant sérialisée en raison d'un conflit de tas), vous devez changer votre utilisation de la bibliothèque/commutateur en une version de conflit ou juste passer à plusieurs processus. La seule façon de savoir est d'écrire des cas de test qui stressent le serveur de diverses manières et de mesurer les résultats.

+0

Je vais certainement écrire le cas de test. mais je voudrais savoir comment est la programmation cpu fait dans Windows théoriquement. cela pourrait m'aider à analyser les tests –

+0

juste pour ajouter un point de plus, nous utilisons VS2008, je suppose qu'il utilise 6.1 sdk. comment pourrais-je confirmer cela ?? –

+0

Peu importe la version du SDK que vous développez: les gains de performances du tas "Windows 7" (Windows version 6.1) sont automatiques dès que vous mettez à niveau le serveur. –