Choix dans quel processeur va s'exécuter un thread [Résolu]

Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 3 juin 2008 à 14:14 - Dernière réponse :
Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 9 juin 2008 à 18:39
Bonjour,

Voila, j'ai un formulaire qui lance sur demande un thread qui exécute des calculs.
Le problème c'est que ces calculs sont assez longs, 15 s, et pendant ce temps, je souhaite pouvoir naviguer dans mon formulaire.
Donc dans ce threads, de temps en temps, j'ai mis l'instruction : Thread.Sleep(0); qui rend la main au système.
Etant donné que mon formulaire utilise des objets graphiques (avec dégradés, path, ...) donc lourds , j'aimerai que le thread de calcul s'exécute sur l'autre processeur (Dual-Core), plutôt que sur celui où le formulaire s'exécute déjà, car sinon mon formulaire se met à rammer.
Bien sur j'aurai pu diminuer le temps processeur alloué au calcul, en mettant par exemple Thread.Sleep(50); mais ca rallonge le temps de calcul à plusieurs minutes.
Donc j'aimerai savoir si vous connaissez des instructions qui permettent de choisir sur quel processeur va s'exécuter un thread.

Merci
Afficher la suite 

Votre réponse

12 réponses

Meilleure réponse
Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 4 juin 2008 à 16:07
3
Merci
Donc j'ai essayer, et ca marche nikel. C'est juste un peu galère pour trouver le n° du thread car il n'y a que par son numéro système que l'on peut y arriver. En fait, la collection récupérée est triée par ordre de création de chaque thread de l'application.  Pour connaitre le n° d'un thread, il suffit de récupérer le dernier objet ProcessThread de la collection juste après la création du thread,  sachant que dans le processus, une fois l'application lancée, il n'y a pas de création de threads supplémentaires (15 environ au démarrage).

Voila comment j'ai procédé :
...
using System.Diagnostics;
using System.Threading;

..................

            ProcessThreadCollection Collection = Process.GetCurrentProcess().Threads;

            foreach (ProcessThread P_Thread in Collection)
            {
                     //Déplacement de tous les threads du processus sur le processeur 1, (le 2 est réservé pour la mesure)
                P_Thread.ProcessorAffinity = new IntPtr(1);  
            }
           
            Thread_mesure = new Thread(Funct_mesure);
            Thread_mesure.IsBackground = true;
            Thread_mesure.Priority = ThreadPriority.Normal;
            Thread_mesure.Start();
           
            //Récupération du n° du dernier Thread créé, afin de le lancer sur l'autre processeur (donc le 2)
            Collection = Process.GetCurrentProcess().Threads;

            Collection[Collection.Count - 1].ProcessorAffinity = new IntPtr(2);   //Collection.Count-1 correspond au dernier thread

...............

Voila ca peut toujours servir, lorsqu'on veut utiliser les ressources CPU à fond (surtout pour les Dual-Core), sachant qu'il est possible de faire changer le thread de processeur pendant son exécution.  On peut par exemple créer un gestionnaire interne de performance. A voir... Si vous avez des objections, des conseils, je prend volontier ^^.

Jdek

Merci jdek 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de jdek
Messages postés
4947
Date d'inscription
lundi 17 février 2003
Dernière intervention
14 février 2014
- 3 juin 2008 à 15:05
0
Merci
hum... Thread.Sleep(...) ne donne pas la main au système ! il met en suspend le thread courrant x millisecondes.

Je te conseille de monter une architecture multhi threading... regarde du coté du BackgroundWorker... voire le Pattern Asynchronous (http://www.csharpfr.com/codes/IMPLEMENTATION-PATTERN-ASYNCHRONOUS_41848.aspx)

Sébastien FERRAND (blog)
Consultant Sénior
[Microsoft Visual C# MVP]
Commenter la réponse de sebmafate
Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 3 juin 2008 à 15:40
0
Merci
Oui, ca met en suspend le thread, mais laisse la main aux autres threads (sinon, ca bloquerai mon formulaire).
Le problème c'est que j'ai besoin d'exécuter au maximum proche du matériel (presque du temps réel), donc je ne peux pas me permettre de gérer  trop d'évènements qui peuvent venir altérer mes calculs.
Avec le BackgroundWorker, est-ce que c'est possible d'attribuer son thread sur un certain processeur ?

Jdek
Commenter la réponse de jdek
Messages postés
4947
Date d'inscription
lundi 17 février 2003
Dernière intervention
14 février 2014
- 3 juin 2008 à 15:47
0
Merci
en .net tu ne peux pas attribuer à un processeur donné une tache.
par contre, en multi-threading, les taches s'exécutent parallèle... et le pattern Asynchronous fonctionne super bien, je l'ai utilisé dans de très gros projets...

Sébastien FERRAND (blog)
Consultant Sénior
[Microsoft Visual C# MVP]
Commenter la réponse de sebmafate
Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 3 juin 2008 à 19:59
0
Merci
Ok merci pour l'info, je vais essayer de regarder ca.

jdek
Commenter la réponse de jdek
Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 3 juin 2008 à 20:41
0
Merci
Si il y en a que ca intéresse, j'ai imaginé une méthode disons barbare , pour "forcer" la gestion du processeur à faire en sorte que le thread soit exécuté sur le processeur où le programme principal ne s'exécute pas.  Lors du start du thread, on fait tourner "à bloc" le processeur sur lequel est le programme principal, ce qui devrait avoir pour effet le démarrage du thread sur l'autre processeur, comme ca par exemple :
int compteur;
do
{
    compteur++;
    if(compteur == 1000)
    {
       monAutreThread.Start(methodeDeMonAutreThread);
    }
}
while(compteur < 1000);

Bon, on ne peut plus artisanal comme méthode ^^, et je n'ai pas encore essayer.  Disons que pour l'instant c'est la seule méthode que je connaisse, peut être que si l'on peut consulter sur quel processeur est exécuter un thread, il y a moyen de se débrouiller plus méthodiquement.  Je vous tiens au courant.
Commenter la réponse de jdek
Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 4 juin 2008 à 11:23
0
Merci
Bon cette méthode marche si le thread est en priorité maximale (Highest), donc on ne peut utiliser cette méthode que si ce thread est le seul à s'exécuter sur le deuxième processeur, sinon il y a risque de fort ralentissement des autres threads.
Je n'est pas encore relevé d'erreur à cette méthode, mais ca pourrai bien arrivé.
(Si un autre programme utilise beaucoup la CPU, cette méthode risque de ne pas marcher).

Jdek
Commenter la réponse de jdek
Messages postés
4947
Date d'inscription
lundi 17 février 2003
Dernière intervention
14 février 2014
- 4 juin 2008 à 11:33
0
Merci
c'est surtout pas propre...

sincèrement, je préfère laisser l'os gérer lui-même les threads.

Sébastien FERRAND (blog)
Consultant Sénior
[Microsoft Visual C# MVP]
Commenter la réponse de sebmafate
Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 4 juin 2008 à 11:51
0
Merci
Je suis bien d'accord,
mais il semble que .net rend possible le changement de processeur : http://msdn.microsoft.com/fr-fr/library/system.diagnostics.processthread.idealprocessor(VS.80).aspx
à essayer.

Jdek
Commenter la réponse de jdek
Messages postés
6366
Date d'inscription
samedi 1 juin 2002
Dernière intervention
2 août 2014
- 7 juin 2008 à 17:26
0
Merci
Salut,

"Pour connaitre le n° d'un thread, il suffit de récupérer le dernier objet ProcessThread de la collection juste après la création du thread"
Heu non, je ne serais pas aussi confiant, il suffit qu'un autre thread crée un nouveau thread entre temps et c'est la fin. En plus je ne suis pas certains que l'ordre de la collection soit garanti.

Le plus "sur" est probablement d'utiliser directement SetThreadAffinityMask en P/Invoke.
Mais ici le plus gros problème est de faire le parallèle entre le thread managé et le thread physique qui est dessous (si c'est bien un thread physique qui est en dessous d'ailleurs).
Bien garder à l'esprit que ce genre de manipulation est à proscrire en dehors du host standard. On manipule le thread réel, ce qui peut être assez problématique si hébergé dans des hosts comme par exemple SQL Server 2005 (voir Thread.BeginThreadAffinity notamment).

Il n'est même pas certains que le thread managé soit implémenté en temps que thread "standard" par le host alternatif (voir Fiber), ce qui peut justement être le cas avec SQL Server il me semble (pas sûr).

/*
coq
MVP Visual C#
CoqBlog
*/
Commenter la réponse de cs_coq
Messages postés
6366
Date d'inscription
samedi 1 juin 2002
Dernière intervention
2 août 2014
- 7 juin 2008 à 17:27
0
Merci
D'ailleurs à y réfléchir, je me demande si le host standard n'est pas lui aussi soumis à variations, notamment d'une version du CLR à l'autre.

/*
coq
MVP Visual C#
CoqBlog
*/
Commenter la réponse de cs_coq
Messages postés
22
Date d'inscription
samedi 8 mars 2008
Dernière intervention
22 avril 2011
- 9 juin 2008 à 18:39
0
Merci
salut,
ok merci pour l'info.
Bien sur la méthode que j'ai posté plus haut fonctionne, mais ce n'est pas de la programmation sure, et elle risque de dépendre d'autres paramètres.
Je n'ai pas le temps actuellement pour faire des tests, mais si j'arrive à faire marcher cette méthode plus sure, je posterai encore ici.

Jdek
Commenter la réponse de jdek

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.