IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Nombre de coeurs/procs d'une machine


Sujet :

C++

  1. #1
    Membre expérimenté Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Par défaut Nombre de coeurs/procs d'une machine
    Bonjour a tous

    Allez, challenge du jour :

    Je cherche une solution pour savoir de combien de coeurs / processeurs l'ordinateur actuel dispose.

    Une solution ( peu élegante ) existe grace au WMI de Windows, malheureusement pour moi, le nombre de coeurs est une information disponible uniquement sous Windows Vista .

    Or, j'aurai besoin, autant que possible, d'une solution disponible sous Mac, Linux, Win Xp/Vista.

    Une solution possible a priori, c'est de recuperer le nom du processeur, ou info equivalente, et en deduire le nombre de coeurs, néanmoins, ça obligerai à modifier le code pour inclure les nouveaux procs de temps en temps.


    Dooonc, des idées ?

    Et merci d'avance pour quoi pourra m'aider...

  2. #2
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Challenge fastoche...

    L'instruction CPUID des processeurs compatibles Intel est faite pour ça.
    Voici mon code pour trouver le nombre de noyaux du processeur exécutant le processus. (fonction num_physical_cores).
    Mais je ne connais pas d'autre manière que d'appeler des fonctions de l'API système pour connaître le nombre de processeurs (fonction GetSystemInfo pour Windows)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    struct cpuid_reg { unsigned int eax,ebx,ecx,edx; };
     
    #if defined(__ICL) || defined(_MSC_VER)
    #include <windows.h>
    inline cpuid_reg _cpuid(unsigned int a, unsigned int c=0)
    {
      cpuid_reg r;
      __try 
      {
        _asm  
        {
          mov eax, a
          mov ecx, c
          cpuid
          mov r.eax, eax
          mov r.ebx, ebx
          mov r.ecx, ecx
          mov r.edx, edx
        }
      } __except (EXCEPTION_EXECUTE_HANDLER) { r.eax=r.ebx=r.ecx=r.edx=0; }
      return r;
    }
    #elif defined(__GNUC__) && (defined(i386)||defined(__x86_64__))
    inline cpuid_reg _cpuid(unsigned int a, unsigned int c=0)
    {
      cpuid_reg r;
      __asm__("cpuid":"=a"(r.eax),"=b"(r.ebx),"=c" (r.ecx),"=d"(r.edx):"a"(a),"c"(c));
      return r;
    }
    #else
    inline cpuid_reg _cpuid(unsigned int a, unsigned int c=0)
    {
      cpuid_reg r={0,0,0,0};
      return r;
    }
    #endif
     
    inline cpuid_reg cpuid(unsigned int a, unsigned int c=0)
    {
      if (a<=_cpuid(0).eax) 
        return _cpuid(a,c);
      cpuid_reg r={0,0,0,0};
      return r;
    }
     
    inline cpuid_reg cpuid_ext(unsigned int a, unsigned int c=0)
    {
      a|=0x80000000;
      if (a<=_cpuid(0x80000000).eax) 
        return _cpuid(a,c);
      cpuid_reg r={0,0,0,0};
      return r;
    }
     
    static char _cpu_vendor[13];
    static char _cpu_name[48];
    inline char *cpu_vendor() { unsigned int *p=(unsigned int *)_cpu_vendor; cpuid_reg reg=cpuid(0); p[0]=reg.ebx; p[1]=reg.edx; p[2]=reg.ecx; _cpu_vendor[12]='\0'; return _cpu_vendor; }
    inline char *cpu_name  () { unsigned int *p=(unsigned int *)_cpu_name; cpuid_reg reg; reg=cpuid_ext(2); p[0]=reg.eax; p[1]=reg.ebx; p[2]=reg.ecx;  p[3]=reg.edx; reg=cpuid_ext(3); p[4]=reg.eax; p[5]=reg.ebx; p[6]=reg.ecx;  p[7]=reg.edx; reg=cpuid_ext(4); p[8]=reg.eax; p[9]=reg.ebx; p[10]=reg.ecx;  p[11]=reg.edx; return _cpu_name; }
    inline bool is_intel_cpu() { return strcmp(cpu_vendor(),"GenuineIntel")==0; }
    inline bool is_amd_cpu  () { return strcmp(cpu_vendor(),"AuthenticAMD")==0; }
    inline bool is_mmx_cpu  () { return (cpuid(1).edx&0x00800000)!=0; }
    inline bool is_sse_cpu  () { return (cpuid(1).edx&0x02000000)!=0; }
    inline bool is_sse2_cpu () { return (cpuid(1).edx&0x04000000)!=0; }
    inline bool is_sse3_cpu () { return (cpuid(1).ecx&0x00000001)!=0; }
     
    inline bool is_3dnow_cpu() { return (cpuid_ext(1).edx&0x80000000)!=0; }
     
    inline unsigned int num_l1_threads      () { return ((cpuid(4,1).eax>>14)&0xFFF)+1; }
    inline unsigned int num_l2_threads      () { return ((cpuid(4,2).eax>>14)&0xFFF)+1; }
    inline unsigned int l1_cache_size       () { cpuid_reg reg=cpuid(4,1); return (((reg.ebx>>22)&0x3FF)+1)*(((reg.ebx>>12)&0x3FF)+1)*((reg.ebx&0xFFF)+1)*(reg.ecx+1); }
    inline unsigned int l2_cache_size       () { cpuid_reg reg=cpuid(4,2); return (((reg.ebx>>22)&0x3FF)+1)*(((reg.ebx>>12)&0x3FF)+1)*((reg.ebx&0xFFF)+1)*(reg.ecx+1); }
    inline unsigned int num_logical_cores   () { cpuid_reg reg=cpuid(1  ); return (reg.edx&0x10000000)?(reg.ebx>>16)&0xFF:1; }
    inline unsigned int num_physical_cores  () { return (!is_amd_cpu()) ? ((cpuid(4,0).eax>>26)&0x03F)+1 : num_logical_cores(); }
    PS: Ce code marche sur les processeurs Intel et AMD (et autres compatibles?), avec les compilos VC,ICL,GCC, et a priori sous n'importe quel système basé sur l'architecture x86 grâce à GCC.

  3. #3
    Membre expérimenté Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Par défaut
    Arf ^_^

    Honte sur moi pour avoir surestimé le probleme

    Merci beaucoup pour ta solution

    Néanmoins, reste le probleme des multi processeurs

    GetSystemInfo pour windows, tu dis ?

    Tu connaitrais pas l'equivalent Linux et Mac, par hasard ?

  4. #4
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Citation Envoyé par Kujara
    GetSystemInfo pour windows, tu dis ?
    Tu peux faire un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #if (defined(__ICL) || defined(_MSC_VER)) && defined(WIN32)
    #include <windows.h>
    inline int num_processors()
    {
      SYSTEM_INFO info;
      GetSystemInfo(&info);
      return info.dwNumberOfProcessors;
    }
    #endif
    Citation Envoyé par Kujara
    Tu connaitrais pas l'equivalent Linux et Mac, par hasard ?
    Non. Faut que tu cherches un peu par toi même...

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Salut,

    Sous linux, tu devrais pouvoir les trouver dans un des sous dossier /proc, non

    Cela fait trop longtemps que je n'ai pas relancé un linux, mais une rapide recherche m'a envoyé vers cat /proc/cpuinfo ou vers une option (non précisée) de uname...

    Creuse peut etre de ce coté là (attention, l'info que j'ai trouvée date de 2005... je ne peux pas assurer que ça n'a pas changé depuis )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Ca c'est la commande depuis un shell.

    Depuis un programme C++ tu peux appeler la fonction sysinfo, en lui passant une structure sysinfo, cette dernirère contient un membre procs qui sera renseigné par l'appel système. L'entête à inclure est <sys/sysinfo.h>.

    Un man sysinfo devrait te donner tous les détails :p

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Citation Envoyé par bolhrak
    Ca c'est la commande depuis un shell.
    Oui, ca, je savais... mais comme il est aussi possible de faire exécuter une commande système depuis C++, c'était peut être quelque chose à creuser
    Depuis un programme C++ tu peux appeler la fonction sysinfo, en lui passant une structure sysinfo, cette dernirère contient un membre procs qui sera renseigné par l'appel système. L'entête à inclure est <sys/sysinfo.h>.

    Un man sysinfo devrait te donner tous les détails :p
    De fait, si un fichier d'en-tête fournis ce qu'il faut, il vaut mieux passer par là
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Citation Envoyé par koala01
    Oui, ca, je savais...
    Yep je me doute c'était juste pour préciser pour l'OP / distinction entre les deux méthodes

    mais comme il est aussi possible de faire exécuter une commande système depuis C++, c'était peut être quelque chose à creuser
    En fait dans la mesure où cette commande ne fait qu'afficher le contenu du fichier sur la sortie shell, en choisissant cette méthode ce serait plus rapide d'aller lire directement le fichier /proc/cpuinfo depuis son programme.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Comme je l'ai indiqué plus haut, cela fait trop longtemps que je n'ai plus lancé linux... mais, de fait, si c'est réellement un fichier, autant peut être "simplement" aller lire dessus (mais est-ce un fichier au sens "C++" du terme )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Pas compris ce que tu entends par fichier au sens "C++" du terme.

    C'est un simple fichier texte, contenant un paragraphe d'infos par proc, du coup obligé de se parcourir tout le fichier pour trouver le nombre de proc :s

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Ce que je voulais dire, c'est "est-il ouvrable, comme n'importe quel fichier texte, à coup de std::ofstream, par exemple "...

    Mais tu as répondu à la question, visiblement
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre expérimenté Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Par défaut
    Excellent ^_^

    Je n'ai malheureusement pas d'ordinateur sous linux sous la main chez moi( juste a mon boulot), donc je ne pourrai essayer cette solution que lundi

    Merci beaucoup a tout le monde !

  13. #13
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Je pourrai te donner la méthode pour mac demain

  14. #14
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Pour Windows j'utilise la même méthode que Charlemagne et pour Mac OS X j'utilise : MPProcessorsScheduled() qui retourne directement le nombre cherché. http://developer.apple.com/documenta...ces/index.html

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Augmenter le nombre d'accès simultanés à une machine distante
    Par Delphi-ne dans le forum Windows Serveur
    Réponses: 5
    Dernier message: 09/07/2014, 21h21
  2. Le nombre des processeurs installé sur une machine
    Par kochfet dans le forum Composants
    Réponses: 4
    Dernier message: 29/05/2014, 15h42
  3. Connaitre le nombre de CPU d'une machine distante
    Par dessinateurttuyen dans le forum Langage
    Réponses: 1
    Dernier message: 11/04/2012, 16h16
  4. nombre de port d'une machine
    Par OLman135 dans le forum Administration système
    Réponses: 5
    Dernier message: 09/07/2009, 15h50
  5. Réponses: 4
    Dernier message: 10/09/2002, 17h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo