Taux d'utilisation du processeur par coeurs dans une appli multi-threads

desperados27 Messages postés 121 Date d'inscription samedi 4 novembre 2006 Statut Membre Dernière intervention 1 juillet 2015 - 8 janv. 2012 à 22:05
desperados27 Messages postés 121 Date d'inscription samedi 4 novembre 2006 Statut Membre Dernière intervention 1 juillet 2015 - 11 janv. 2012 à 10:14
Bonjour,
J'espère poster dans le bon thème !

Je pose une question par curiosité sur la charge processeur dans une appli. Je ne trouve pas de réponse sur internet au 'problème' (même si c'en est pas un) suivant :


-Mon appli est multi-threadée sur une opération spécifique.
-Le nombre de Threads est calé sur le nombre de coeurs de l'ordinateur : dans mon cas 4 (j'ai essayé avec plus de Threads (8,16,64) mais ça ne change rien)
-La charge du processeur est de 50% maxi (ne descend pas en dessous de 40%) !!
Plus en détail : la charge par coeur est également de maximum 50 % (ne descend pas en dessous de 40%) !!!
-Tous les coeurs sont bien utlisés et ne tombent pas en dessous de 40% durant tout le temps du traitement.
-La priorité de mes Threads est sur ThreadPriority.AboveNormal (j'ai déjà essayé le ThreadPriority.Highest, rien ne change)

La question est simple : Pourquoi je ne peux pas aller au delà de 50% de charge processeur ?

Merci d'avance pour vos lumières
Sébastien

8 réponses

NHenry Messages postés 15030 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 26 novembre 2022 157
8 janv. 2012 à 23:03
Bonjour,

Plusieurs facteurs peuvent entrer en compte, voici quelques uns :
- Si il y a une synchro entre lmes thread (Synclock et autre), ça peut baisser le taux.
- Tu forces l'activation du GC, cela mets en pause tout le programme
- Autre

C'est assez court, mais je n'ai pas encore eu l'occasion de bien me pencher sur ce détail (je ne suis que double coeur, comme le Docteur :D ).

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, ce lien ou encore celui-ci[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
0
desperados27 Messages postés 121 Date d'inscription samedi 4 novembre 2006 Statut Membre Dernière intervention 1 juillet 2015
9 janv. 2012 à 00:26
Je n'utilise rien de spécial :

                var tThreads = new Thread[nbCoeurs * factCoeurs]; // factCoeur détermine juste combien de threads je met par coeurs
                for (int i = 0; i < nbCoeurs * factCoeurs; i++)
                {
                    tThreads[i] = new Thread(RemplirASC);
                    tThreads[i].Name = i.ToString();
                    tThreads[i].Priority = ThreadPriority.AboveNormal;
                    tThreads[i].Start();
                }
                for (int i = 0; i < nbCoeurs * factCoeurs; i++)
                    tThreads[i].Join();



        public static void RemplirASC()
        {
            int indexThread= int.Parse(Thread.CurrentThread.Name);
            for (int i = indexThread; i < VariablesCollection.Count; i += nbCoeurs * factCoeurs)
            {
                  // Blabla
            }
        }


C'est vraiment rien de bien méchant, mais si ça peut vous éclairer...
Je n'ai rien fait de plus
0
desperados27 Messages postés 121 Date d'inscription samedi 4 novembre 2006 Statut Membre Dernière intervention 1 juillet 2015
9 janv. 2012 à 15:57
En fait je met à jour ....

Même avec seulement le thread principal la charge ne dépasse pas 50%. De plus j'ai essayé sur un 2 coeurs (donc une autre machine), toujours pareil.

J'ai lancé TES5 (un jeu) pour voir si c'était pas le processeur qui était mal en point mais non j'ai bien 100% charge sur au moins un coeur. :/

Je me demande si les appli .NET sont bridées ?
0
NHenry Messages postés 15030 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 26 novembre 2022 157
9 janv. 2012 à 18:51
Bonjour,

Je n'ai pas trouvé beaucoup de literrature à ce sujet, J'ai peut être pas utilisé les bons mots clés.

Je n'ai pas d'explication à te fournir, dsl.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, ce lien ou encore celui-ci[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_coq Messages postés 6351 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 100
9 janv. 2012 à 20:53
Bonjour,

Non il n'y a pas de bridage.
Si le code n'attend jamais (I/O, verrou, ...) la boucle devrait consommer plus ou moins l'équivalent d'un coeur.


/*
coq
CoqBlog
*/
0
desperados27 Messages postés 121 Date d'inscription samedi 4 novembre 2006 Statut Membre Dernière intervention 1 juillet 2015
10 janv. 2012 à 12:03
Bonjour à vous,

Nhenry, je ne trouve aucune info moi non plus sur la charge du processeur en fonction de ce que l'on fait dans le code ; c'est assez bizarre.

coq, non je ne fait qu'assigner à un tableau de string du texte en cherchant des infos dans une collection d'objets...


Alors, j'ai pas mal regardé depuis avant-hier... Je pense qu'il y a une limitation niveau hardware ! Et plus précisement niveau mémoire vive !

Je mexplique : j'ai fait le test en recréant un projet Console.. J'ai fait exactement pareil que le code ci-dessus sauf que j'ai seulement fait :

PS : J'utilise 8 threads pour être sûr d'utiliser toutes les ressources. (car 4 threads me met à 80-90%)

            int indexThread= int.Parse(Thread.CurrentThread.Name);
            for (int i = indexThread; i < 100000000; i += nbThreads)
                  Console.WriteLine(i);


Ici j'ai bien 100% d'utilisation en continue sur chaque coeur avec pas trop de mémoire utilisée.

Mais voilà maitenant je veux faire:
            int indexThread= int.Parse(Thread.CurrentThread.Name);
            string test = "blabla";
            for (int i = indexThread; i < 100000000; i += nbThreads)
                  test += "," + test;


Ici la charge processeur ne dépasse pas 65% sur chaque coeur et l'utilisation de la mémoire vive est intense !
PS : en déboublant 'test += "," + test;' plusieurs fois ma mémoire vive arrive à saturation (3.99Go utilisés...).

J'en arrive à la conclusion que pour certains type de variables, d'objets ou d'opérations faites il arrive à un moment où la mémoire vive (ou paginée en cas de saturation) ne suive plus !

Je sais que sur mon PC, ma DDR3 est à la plus basse fréquence (1066Mhz). Je pense réellement que si j'avais du 1333Mhz ou bien du 1600Mhz ça irait beaucoup mieux !

Enfin c'est ma théorie !
Essayez si vous êtes curieux de savoir !

Sébastien
0
cs_coq Messages postés 6351 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 100
11 janv. 2012 à 01:13
           int indexThread= int.Parse(Thread.CurrentThread.Name);
            string test = "blabla";
            for (int i = indexThread; i < 100000000; i += nbThreads)
                  test += "," + test;


Heu, si tu as utilisé ce code précis pour ces tests il n'est pas vraiment étonnant que la consommation mémoire grimpe en flèche et pas trop étonnant que la conso CPU ne soit pas à fond.

A chaque tour de boucle la taille de la nouvelle chaine de caractères est égale à 2 fois la taille de la précédente (+1), et la précédente chaine de caractère est disponible pour garbage collection (qui pour le coup doit se déclencher souvent).
Avec une boucle de 100000000 itérations (un thread) on parle d'une chaine de caractères d'une longueur finale énorme.

Si l'application est compilée en x86 ça doit rapidement finir en OutOfMemory, sur du x64 la machine doit passer son temps à étendre le fichier de pagination et à faire des I/O disque.


/*
coq
CoqBlog
*/
0
desperados27 Messages postés 121 Date d'inscription samedi 4 novembre 2006 Statut Membre Dernière intervention 1 juillet 2015
11 janv. 2012 à 10:14
Tout à fait d'accord, oui je suis en x64 et le fichier de pagination s'étend en continue.

Par contre pourquoi ce :
pas trop étonnant que la conso CPU ne soit pas à fond


Je parle pas quand la mémoire est saturée (car sinon dans ce cas précis la conso cpu est presque nulle comme tu dis !)
0