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

Delphi Discussion :

[CPUID] Questions autour du CPU


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 47
    Par défaut [CPUID] Questions autour du CPU
    Voici différentes question en rapport avec le CPU et l'instruction CPUID

    (Voir le code ci-dessous)
    A quoi correspondent L1ICache et L1DCache pour le cache de niveau 1 ?
    Alors qu'on a un GetExtendedL2Cache unique pour le cache de niveau 2 ?

    Le cache de niveau 1 me renvoie toujours 0 ! que ce soit L1ICache ou L1DCache alors que j'ai 16 Ko par contre pour le niveau 2 il me renvoie bien 2048 Ko (2Mo) ce qui correspond bien. Ya t-il une combinaison arithmétique de L1ICache et L1DCache pour obtenir la valeur du cache de niveau 1 ? ou est-ce la routine qui est en cause dans ce cas je suis preneur pour une autre routine qui fonctionnerais mieux ???

    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
     
    type
     TCPUIDResult = packed record  {getCPUInfo}
       EAX: DWord;
       EBX: DWord;
       ECX: DWord;
       EDX: DWord;
     end;
     
     TCPUInfo =packed record       {getCPUInfo}
       Name: string[48];
       Brand: Word;
       APIC: DWORD;
       Vendor: string[12];
       Frequency: Real;
       Family: integer;
       Model: integer;
       Stepping: integer;
       EFamily: integer;
       EModel: integer;
       EStepping: integer;
       FPU: Boolean; //Test
       PSN: Boolean;
       MMX: Boolean;
       FXSAVE : Boolean;
       MMXPlus: Boolean;
       AMD3DNow: Boolean;
       AMD3DNowPlus: Boolean;
       SSE : Boolean;
       SSE2: Boolean;
       HTT : Boolean;
       SSE3: Boolean;
       IA64: Boolean;
       X86_64: Boolean;
       L1DCache:word; //Cache CPU Level 1
       L1ICache:word;
       L2Cache:word;  //cache CPU Level 2
     end;
     
    var   CPUID : TCPUID;
     
    begin
     
          { Détermine le cache CPU de niveau 1 (L1) }
          ListItem := ListView1.Items.Add;
          ListItem.Caption := 'Cache de niveau 1';
          ListItem.SubItems.Add(inttostr(GetExtendedL1ICache)+ ' Ko');
     
         { Détermine le cache CPU de niveau 2 (L2) }
          ListItem := ListView1.Items.Add;
          ListItem.Caption := 'Cache de niveau 2';
          ListItem.SubItems.Add(inttostr(GetExtendedL2Cache)+ ' Ko');
    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    //****************************************************
    // Renvoie la taille des caches de niveau L1 et L2 du CPU
    //****************************************************
    //uses Math (Instruction Power)
    function GetExtendedL1DCache:word;  //L1 cache
    var L1D,TempL1D:dword;
        BinArray:array[0..31] of byte;
        i,p:integer;
    begin
    asm
      push eax
      push ebx
      push ecx
      push edx
      mov eax,$80000005
      mov ebx,0
      mov ecx,0
      mov edx,0
      db $0F,$A2               /// cpuid
      mov L1D,ecx
      pop edx
      pop ecx
      pop ebx
      pop eax
    end;
    for i:=0 to 31 do
      begin
       BinArray[i]:=L1D mod 2;
       L1D:=L1D div 2;
      end;
    TempL1D:=0;
    p:=0;
    for i:=24 to 31 do
      begin
       TempL1D:=TempL1D+(BinArray[i]*StrToInt(FloatToStr(Power(2,p))));
       inc(p);
      end;
    GetExtendedL1DCache:=TempL1D;
    end;
     
    function GetExtendedL1ICache:word;
    var L1I,TempL1I:dword;
        BinArray:array[0..31] of byte;
        i,p:integer;
    begin
    asm
      push eax
      push ebx
      push ecx
      push edx
      mov eax,$80000005
      mov ebx,0
      mov ecx,0
      mov edx,0
      db $0F,$A2               /// cpuid
      mov L1I,edx
      pop edx
      pop ecx
      pop ebx
      pop eax
    end;
    for i:=0 to 31 do
      begin
       BinArray[i]:=L1I mod 2;
       L1I:=L1I div 2;
      end;
    TempL1I:=0;
    p:=0;
    for i:=24 to 31 do
      begin
       TempL1I:=TempL1I+(BinArray[i]*StrToInt(FloatToStr(Power(2,p))));
       inc(p);
      end;
    GetExtendedL1ICache:=TempL1I;
    end;
     
     
    function GetExtendedL2Cache:word;
    var L2,TempL2:dword;
        BinArray:array[0..31] of byte;
        i,p:integer;
    begin
    asm
      push eax
      push ebx
      push ecx
      push edx
      mov eax,$80000006
      mov ebx,0
      mov ecx,0
      mov edx,0
      db $0F,$A2               /// cpuid
      mov L2,ecx
      pop edx
      pop ecx
      pop ebx
      pop eax
    end;
    for i:=0 to 31 do
      begin
       BinArray[i]:=L2 mod 2;
       L2:=L2 div 2;
      end;
    TempL2:=0;
    p:=0;
    for i:=16 to 31 do
      begin
       TempL2:=TempL2+(BinArray[i]*StrToInt(FloatToStr(Power(2,p))));
       inc(p);
      end;
    GetExtendedL2Cache:=TempL2;
    end;
    Je détecte la présence du PSN (Processor Serial Number comme ceci) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
          //PSN (Intel Processor Serial Number)
          ListItem := ListView1.Items.Add;
          ListItem.Caption := 'PSN';   //bit 23
          if CPU.PSN then begin
            //ListItem.SubItems.Add(GetPSN);
          end
          else begin
            ListItem.SubItems.Add('(Aucun ou désactivé)' );
          end;
    Mais j'aimerais adapter le code ci-dessous trouvé sur le net à la syntaxe de mon code (les 2 codes ci-dessus) afin de pouvoir afficher le processor Serial Number (PSN) si existant :

    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
     
    var  
      _eax, _ebx, _ecx, _edx: Longword; 
      i: Integer; 
      b: Byte; 
      b1: Word; 
      s, s1, s2, s3, s_all: string; 
    begin 
      b := lo(_ebx shr 16); 
      info('   - ' + 'Count: ', IntToStr(b)); 
      b := hi(_ebx shr 16); 
      info('   - ' + 'APIC ID: ', IntToStr(b)); 
      //Bit 18 =? 1     //is serial number enabled? 
      if (_edx and $40000) = $40000 then 
        info('   - ' + 'Serial Number ', 'Enabled') 
      else  
        info('   - ' + 'Serial Number ', 'Disabled'); 
      s := IntToHex(_eax, 8); 
      asm                  //determine the serial number 
        mov eax,3 
        db $0F,$A2 
        mov _ecx,ecx 
        mov _edx,edx 
      end; 
      s1 := IntToHex(_edx, 8); 
      s2 := IntToHex(_ecx, 8); 
      Insert('-', s, 5); 
      Insert('-', s1, 5); 
      Insert('-', s2, 5); 
      info('   - ' + 'Serial Number: ', s + '-' + s1 + '-' + s2); 
      asm 
        mov eax,1 
        db $0F,$A2 
        mov _edx,edx 
      end; 
      info('', ''); 
      //Bit 23 =? 1 
      if (_edx and $800000) = $800000 then 
        info('MMX ', 'Supported') 
      else  
        info('MMX ', 'Not Supported');
    Merci,

    Denis

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 47
    Par défaut
    J'ai trouvé un code en C interressant dans le forum :
    http://www.developpez.net/forums/sho...d.php?t=325148

    avec physical_core_count (nb de cpu physique ?)
    et cache-size L1 et L2 : Mais comment les adapter à mon code ?

    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
     
    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;
    }
     
    unsigned int physical_core_count    () { return ((cpuid(4,0).eax>>26)&0x03F)+1; }
    unsigned int logical_processor_count() { cpuid_reg reg = cpuid(1  ); return (reg.edx&0x10000000)?(reg.ebx>>16)&0xFF:1; }
    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); }
    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); }

Discussions similaires

  1. Réponses: 1
    Dernier message: 31/10/2008, 16h58
  2. Question autour de sp_executesql
    Par Colon dans le forum Développement
    Réponses: 3
    Dernier message: 29/05/2008, 12h18
  3. Questions autours du pathfinding
    Par valefor dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 25/07/2007, 19h41
  4. Trois questions autour de Windows Server
    Par Kain94 dans le forum Windows Serveur
    Réponses: 5
    Dernier message: 07/08/2006, 10h32
  5. [JSF] Questions autour des servlets
    Par maximus001ma dans le forum JSF
    Réponses: 4
    Dernier message: 25/07/2006, 13h27

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