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

API, COM et SDKs Delphi Discussion :

[D6] Processus - temps processeur


Sujet :

API, COM et SDKs Delphi

  1. #1
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut [D6] Processus - temps processeur
    Est-il possible de savoir si un processus est en train de travailler, ou est simplement actif ?

    En gros, si dans le gestionnaire des tâches, il y a une valeur supérieure à zéro dans la colonne processeur, ou pas.
    Je pense au processus de mise à jour de l'antivirus. J'aimerais savoir (au moment où j'interrogerais) si l'exe est en train de faire une mise-à-jour, ou s'il est simplement en attente.

    Une idée ?

    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Tu as déjà GetProcessTimes pour les valeurs brutes, puis NdisGetCurrentProcessorCounts te donnera la formule à appliquer pour avoir la charge CPU (forcément approximative en mode User). Il te suffit en gros de sampler le processus pendant une brève période (disons 100 ms) pour avoir une estimation du pourcentage de CPU qu'il consomme.

    Tu dois pouvoir te contenter de deux samplings : un à T0 et un à T100 pour faire le calcul (récupérer le temps écoulé "exact" via QueryPerformanceCounter plutôt que par GetTickCount). Plus tu "testes" longtemps ton processus, plus le chiffre sera exact, reste à savoir le délai que tu estimes raisonnable pour lancer ton action (100 ms ? 500 ms ? 1 s ?)

    Autre solution, plus exacte mais peut-être plus lourde à mettre en place : Collecting Performance Data.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #3
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    pour ta réponse.
    Effectivement, ça m'a l'air de correspondre à ce que je cherche.
    Pour la procédure NdisGetCurrentProcessorCounts, je lis ici (http://msdn.microsoft.com/en-us/library/bb625382.aspx) que c'est défini dans Ndis.h. Mais, en Delphi je ne vois pas comment y accéder.
    J'imagine que cette procédure est accessible depuis une DLL windows, mais je n'ai pas trouvé laquelle (et je ne suis pas le seul http://www.developpez.net/forums/d68...ibrairie-ndis/).
    Tu n'aurais pas une idée ?

    Citation Envoyé par Mac LAK Voir le message
    Autre solution, plus exacte mais peut-être plus lourde à mettre en place : Collecting Performance Data.
    Pour cette solution, je n'ai pas compris.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Lung Voir le message
    J'imagine que cette procédure est accessible depuis une DLL windows, mais je n'ai pas trouvé laquelle (et je ne suis pas le seul http://www.developpez.net/forums/d68...ibrairie-ndis/).
    Tu n'aurais pas une idée ?
    C'est une fonction kernel, tu ne peux pas y accéder. L'intérêt de cette fonction ne réside QUE dans la formule décrite dans son aide.
    Et pour les timings, tu utilises QueryPerformanceCounter + GetProcessTimes afin d'avoir le temps CPU du processus entre deux références temporelles, ce qui te permettra (via la formule précitée) d'obtenir la charge estimée du processus.

    Citation Envoyé par Lung Voir le message
    Pour cette solution, je n'ai pas compris.
    C'est la manière de lancer les analyseurs de performance Windows. C'est un poil complexe en effet, laisse tomber si tu ne t'en sens pas le niveau, au profit de la première solution.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    C'est une fonction kernel, tu ne peux pas y accéder. L'intérêt de cette fonction ne réside QUE dans la formule décrite dans son aide.
    Ah ok.

    CpuUsage = 100-100*(Idle - Idle[n])/(KernelAndUser - KernelAndUser[n]);
    Mais, il me manque le Idle.
    GetProcessTimes ne me le donne pas.

    Voilà où j'en suis :
    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
    var
       hProcessHandle: THandle;
       nDebut, nFin, nKernelTime1, nUserTime1, nKernelTime2, nUserTime2: Int64;
       lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: _FILETIME;      // TFileTime
       lpsKernelTime, lpsUserTime: _SYSTEMTIME;
    begin
       hProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessEntry.th32ProcessID);
       try
          if not GetProcessTimes(hProcessHandle, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime) then
          begin
             Application.MessageBox(PChar('GetProcessTimes 1' + #13#10 + SysErrorMessage(GetLastError)), PChar(Caption + ' - erreur'), MB_ICONERROR + MB_OK);
             Exit;
          end;
          if not FileTimeToSystemTime(lpKernelTime, lpsKernelTime) then
             Exit;
          nKernelTime1 := (lpsKernelTime.wHour * 60 * 60 * 1000) + (lpsKernelTime.wMinute * 60 * 1000) + (lpsKernelTime.wSecond * 1000) + lpsKernelTime.wMilliseconds;
          if not FileTimeToSystemTime(lpUserTime, lpsUserTime) then
             Exit;
          nUserTime1 := (lpsUserTime.wHour * 60 * 60 * 1000) + (lpsUserTime.wMinute * 60 * 1000) + (lpsUserTime.wSecond * 1000) + lpsUserTime.wMilliseconds;
    
          //.Pause (nano-secondes).
          QueryPerformanceCounter(nDebut);
          repeat
             QueryPerformanceCounter(nFin);
          until((nFin - nDebut) > 5000000);
    
          if not GetProcessTimes(hProcessHandle, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime) then
          begin
             Application.MessageBox(PChar('GetProcessTimes 2' + #13#10 + SysErrorMessage(GetLastError)), PChar(Caption + ' - erreur'), MB_ICONERROR + MB_OK);
             Exit;
          end;
          if not FileTimeToSystemTime(lpKernelTime, lpsKernelTime) then
             Exit;
          nKernelTime2 := (lpsKernelTime.wHour * 60 * 60 * 1000) + (lpsKernelTime.wMinute * 60 * 1000) + (lpsKernelTime.wSecond * 1000) + lpsKernelTime.wMilliseconds;
          if not FileTimeToSystemTime(lpUserTime, lpsUserTime) then
             Exit;
          nUserTime2 := (lpsUserTime.wHour * 60 * 60 * 1000) + (lpsUserTime.wMinute * 60 * 1000) + (lpsUserTime.wSecond * 1000) + lpsUserTime.wMilliseconds;
    
          _dTempsProcesseur := 100 - 100 * ( ? ) / (nKernelTime1 + nUserTime1) - (nKernelTime2 + nUserTime2);
       finally
          CloseHandle(hProcessHandle);
       end;
    Sinon, le jonglage entre les _FILETIME et les _SYSTEMTIME, c'est pas simple.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Lung Voir le message
    Mais, il me manque le Idle.
    Tu peux l'obtenir avec GetLastInputInfo, c'est expliqué dans l'aide de la structure passée en paramètre.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #7
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Je n'avais pas vu cette fonction.
    Maintenant, j'ai tous ce que réclame la formule magique.
    Je l'ai testée, mais les seules valeurs que j'obtiens sont soit 0, soit 100, soit un gros décimal négatif.
    Je m'attendais à un pourcentage. C'est normal comme résultat, ou j'ai encore raté quelque chose ?

    En tout cas, quand le processus est en pleine activité, j'ai la valeur 100, donc j'ai bien ce que je recherche.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  8. #8
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Lung Voir le message
    En tout cas, quand le processus est en pleine activité, j'ai la valeur 100, donc j'ai bien ce que je recherche.
    Tu n'aurais pas tout simplement une division entière dans ton résultat au lieu d'une division en flottant, qui rendrait donc "0" ou "1" au lieu d'avoir un chiffre décimal entre les deux ?
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  9. #9
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Tu n'aurais pas tout simplement une division entière dans ton résultat au lieu d'une division en flottant, qui rendrait donc "0" ou "1" au lieu d'avoir un chiffre décimal entre les deux ?
    Euh ... pas tout compris.

    Voici le calcul :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _dTempsProcesseur := 100 - 100 * (nIdle2 - nIdle1) / ((nKernelTime2 + nUserTime2) - (nKernelTime1 + nUserTime1));
    _dTempsProcesseur est un double, et les autres variables des Int64 pour les milli-secondes.

    J'aurais encore un problème de parenthèses ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  10. #10
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Lung Voir le message
    Voici le calcul :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _dTempsProcesseur := 100 - 100 * (nIdle2 - nIdle1) / ((nKernelTime2 + nUserTime2) - (nKernelTime1 + nUserTime1));
    _dTempsProcesseur est un double, et les autres variables des Int64 pour les milli-secondes.
    Non, des problèmes de cast : tes opérations ne portent QUE sur des entiers, il te faut les forcer à passer en flottants AVANT la division. L'idéal pour ça, et qui évite le cast sauvage, c'est d'utiliser une ou deux variables temporaires et de décomposer le calcul. Le compilateur optimise assez bien : pas d'inquiétude à avoir sur les perfs (hors compilation en debug bien sûr, mais on se fiche des perfs dans ce cas).

    Refais ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Var
      dDeltaIdle, cDeltaLoad, dTempsProcesseur : Double ;
    Begin
    ....
    dDeltaIdle := (nIdle2 - nIdle1) ;
    cDeltaLoad := (nKernelTime2 + nUserTime2) - (nKernelTime1 + nUserTime1) ;
    dTempsProcesseur := dDeltaIdle / dDeltaLoad ;
    dTempsProcesseur := 100- 100 * dTempsProcesseur ;
    (Note : évite les variables préfixées par "_", tu peux avoir parfois des effets indésirables lors du lien avec du code C...)
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  11. #11
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Non, des problèmes de cast : tes opérations ne portent QUE sur des entiers, il te faut les forcer à passer en flottants AVANT la division. L'idéal pour ça, et qui évite le cast sauvage, c'est d'utiliser une ou deux variables temporaires et de décomposer le calcul. Le compilateur optimise assez bien : pas d'inquiétude à avoir sur les perfs (hors compilation en debug bien sûr, mais on se fiche des perfs dans ce cas).

    Refais ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Var
      dDeltaIdle, cDeltaLoad, dTempsProcesseur : Double ;
    Begin
    ....
    dDeltaIdle := (nIdle2 - nIdle1) ;
    cDeltaLoad := (nKernelTime2 + nUserTime2) - (nKernelTime1 + nUserTime1) ;
    dTempsProcesseur := dDeltaIdle / dDeltaLoad ;
    dTempsProcesseur := 100- 100 * dTempsProcesseur ;
    Ca ne change rien au niveau du résultat.
    J'ai toujours 0 quand il fait rien, et 100 quand il est en activité.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  12. #12
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Tu effectue la mesure pendant combien de temps ?
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  13. #13
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Tu effectue la mesure pendant combien de temps ?
    Je fais ça entre deux mesures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          QueryPerformanceCounter(nDebut);               
          repeat
             QueryPerformanceCounter(nFin);
          until((nFin - nDebut) > 5000000000);
    Ca semble correspondre à environ 2 secondes.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  14. #14
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Vaudrait mieux un truc dans ce genre, plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    QueryPerformanceCounter(nDebut);
    Sleep(500);
    QueryPerformanceCounter(nFin);
    Parce que ton code précédent va, à priori, bouffer 100% du temps CPU...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  15. #15
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Vaudrait mieux un truc dans ce genre, plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    QueryPerformanceCounter(nDebut);
    Sleep(500);
    QueryPerformanceCounter(nFin);
    Parce que ton code précédent va, à priori, bouffer 100% du temps CPU...
    Alors là, je ne comprend plus.
    A quoi sert QueryPerformanceCounter, si la pause est faite par Sleep ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  16. #16
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Lung Voir le message
    Alors là, je ne comprend plus.
    A quoi sert QueryPerformanceCounter, si la pause est faite par Sleep ?
    L'appel à QPF permet d'avoir un timestamp absolu et identique sur tous les processus. Le Sleep, lui, permet à ton processus de ne pas bouffer 100% du temps CPU sur la boucle, ce qui faussera forcément les mesures de charge de l'AUTRE processus, celui que tu mesures.

    A moins que je n'ai pas bien compris, et que tu ne cherches pas à connaître le %CPU d'un processus externe à partir de ton application ?
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  17. #17
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    L'appel à QPF permet d'avoir un timestamp absolu et identique sur tous les processus.
    Je ne comprend pas. C'est quoi un timestamp ?
    Les définitions que j'ai trouvé sur le net, ne m'ont pas beaucoup éclairé.

    Citation Envoyé par Mac LAK Voir le message
    Le Sleep, lui, permet à ton processus de ne pas bouffer 100% du temps CPU sur la boucle, ce qui faussera forcément les mesures de charge de l'AUTRE processus, celui que tu mesures.
    Ca je comprend bien.

    Citation Envoyé par Mac LAK Voir le message
    A moins que je n'ai pas bien compris, et que tu ne cherches pas à connaître le %CPU d'un processus externe à partir de ton application ?
    Si, si, c'est bien ça.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  18. #18
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Lung Voir le message
    Je ne comprend pas. C'est quoi un timestamp ?
    Les définitions que j'ai trouvé sur le net, ne m'ont pas beaucoup éclairé.
    C'est une mesure temporelle fiable, déterministe et permettant de calculer précisément la chronologie d'évènements et/ou le temps écoulé entre deux évènements quelconques. Typiquement, cela peut être une datation, comme celle des fichiers de log, une horloge de référence, ou n'importe quoi d'autre.

    Dans notre cas, le QPF est une horloge de référence relative : sa valeur réelle n'a aucun sens (sauf mesurer depuis combien de temps le CPU est allumé), c'est la différence entre deux acquisitions du QPF qui a un sens. C'est exactement la même chose pour GetTickCount, dont la valeur n'a aucun sens, seule la différence compte.

    Une horloge de référence absolue permet, elle, de savoir très exactement la date de l'évènement. Une source NTP est, par exemple, une horloge absolue, tout comme la date/heure de ton PC. Bien entendu, une horloge absolue peut aussi fonctionner comme une horloge relative, la réciproque étant fausse.


    Dans ton cas, n'oublie pas de convertir les mesures du QPF via la valeur obtenue avec QueryPerformanceFrequency, de façon à obtenir une valeur correcte : n'oublie pas que GetProcessTimes renvoie une valeur précise à 100 nanosecondes près, le QPF est souvent bien plus précis que ça, alors que GetLastInputInfo te renverras des millisecondes... Bref, il te faudra tout convertir en millisecondes pour ne pas être ennuyé dans tes calculs.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  19. #19
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    C'est une mesure temporelle fiable, déterministe et permettant de calculer précisément la chronologie d'évènements et/ou le temps écoulé entre deux évènements quelconques. Typiquement, cela peut être une datation, comme celle des fichiers de log, une horloge de référence, ou n'importe quoi d'autre.

    Dans notre cas, le QPF est une horloge de référence relative : sa valeur réelle n'a aucun sens (sauf mesurer depuis combien de temps le CPU est allumé), c'est la différence entre deux acquisitions du QPF qui a un sens. C'est exactement la même chose pour GetTickCount, dont la valeur n'a aucun sens, seule la différence compte.
    Ok. Je vois un peu mieux.

    Citation Envoyé par Mac LAK Voir le message
    Dans ton cas, n'oublie pas de convertir les mesures du QPF via la valeur obtenue avec QueryPerformanceFrequency, de façon à obtenir une valeur correcte : n'oublie pas que GetProcessTimes renvoie une valeur précise à 100 nanosecondes près, le QPF est souvent bien plus précis que ça, alors que GetLastInputInfo te renverras des millisecondes... Bref, il te faudra tout convertir en millisecondes pour ne pas être ennuyé dans tes calculs.
    J'utilisais FileTimeToSystemTime pour faire la conversion, et récupérer les millisecondes.

    Voici mon code (ça sera plus simple):
    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
    var
       hProcessHandle: THandle;
       lii: tagLASTINPUTINFO;
       nDebut, nFin, nIdle1, nKernelTime1, nUserTime1, nIdle2, nKernelTime2, nUserTime2: Int64;
       lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: _FILETIME;      // TFileTime
       lpsKernelTime, lpsUserTime: _SYSTEMTIME;
       dDeltaIdle, dDeltaKernelUser: Double;
    begin
       hProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessEntry.th32ProcessID);
       try
          //### PREMIERE MESURE. ###
          lii.cbSize := SizeOf(tagLASTINPUTINFO);
          if not GetLastInputInfo(lii) then
             Exit;
          nIdle1 := lii.dwTime;
     
          if not GetProcessTimes(hProcessHandle, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime) then
          begin
             Application.MessageBox(PChar('GetProcessTimes 1' + #13#10 + SysErrorMessage(GetLastError)), PChar(Caption + ' - erreur'), MB_ICONERROR + MB_OK);
             Exit;
          end;
          if not FileTimeToSystemTime(lpKernelTime, lpsKernelTime) then
             Exit;
          nKernelTime1 := (lpsKernelTime.wHour * 60 * 60 * 1000) + (lpsKernelTime.wMinute * 60 * 1000) + (lpsKernelTime.wSecond * 1000) + lpsKernelTime.wMilliseconds;
          if not FileTimeToSystemTime(lpUserTime, lpsUserTime) then
             Exit;
          nUserTime1 := (lpsUserTime.wHour * 60 * 60 * 1000) + (lpsUserTime.wMinute * 60 * 1000) + (lpsUserTime.wSecond * 1000) + lpsUserTime.wMilliseconds;
     
          //### Pause. ###
          QueryPerformanceCounter(nDebut);
          Sleep(500);
          QueryPerformanceCounter(nFin);
    //      repeat
    //         QueryPerformanceCounter(nFin);
    //      until((nFin - nDebut) > 5000000000);
     
          // ### DEUXIEME MESURE.  ###
          if not GetLastInputInfo(lii) then
             Exit;
          nIdle2 := lii.dwTime;
     
          if not GetProcessTimes(hProcessHandle, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime) then
          begin
             Application.MessageBox(PChar('GetProcessTimes 2' + #13#10 + SysErrorMessage(GetLastError)), PChar(Caption + ' - erreur'), MB_ICONERROR + MB_OK);
             Exit;
          end;
          if not FileTimeToSystemTime(lpKernelTime, lpsKernelTime) then
             Exit;
          nKernelTime2 := (lpsKernelTime.wHour * 60 * 60 * 1000) + (lpsKernelTime.wMinute * 60 * 1000) + (lpsKernelTime.wSecond * 1000) + lpsKernelTime.wMilliseconds;
          if not FileTimeToSystemTime(lpUserTime, lpsUserTime) then
             Exit;
          nUserTime2 := (lpsUserTime.wHour * 60 * 60 * 1000) + (lpsUserTime.wMinute * 60 * 1000) + (lpsUserTime.wSecond * 1000) + lpsUserTime.wMilliseconds;
     
          // ### CALCUL ###
          //.NdisGetCurrentProcessorCounts [CpuUsage = 100-100*(Idle - Idle[n])/(KernelAndUser - KernelAndUser[n])].
          dDeltaIdle := (nIdle2 - nIdle1);
          dDeltaKernelUser := (nKernelTime2 + nUserTime2) - (nKernelTime1 + nUserTime1);
          if dDeltaKernelUser = 0 then
             dTempsProcesseur := 0
          else
          begin
             dTempsProcesseur := dDeltaIdle / dDeltaKernelUser;
             dTempsProcesseur := 100 - 100 * _dTempsProcesseur;
          end;
       finally
          CloseHandle(hProcessHandle);
       end;
    Y a t'il quelque chose que je ne ferais pas bien ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  20. #20
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    A vue de nez, je dirais :
    • Pas de calculs entre les mesures "début" et "fin", ça fausse les mesures.
    • Ton appel à QPF ne sert à rien, vu que tu utilises GetProcessTimes et le temps en Idle du système.
    • Ordre des appels :
      • Ouverture process + tests (ex : mesure "pour rien").
      • GetLastInputInfo(début)
      • GetProcessTimes(début)
      • Sleep
      • GetLastInputInfo(fin)
      • GetProcessTimes(fin)
      • Calculs.
    • A des fins de debug, tu devrais afficher toutes les valeurs intermédiaires avant (et après) avoir fait les calculs, de façon à voir "à l'œil" les mesures étranges.
    Pour le reste, je n'ai pas de quoi tester sous le coude, donc il faudra que tu le fasses et que tu mettes les résultats ici pour pouvoir t'aider au diagnostic.

    Mais dans tous les cas, ne trouver QUE 0 ou 100 comme valeurs, c'est anormal et cela sous-entends que tu as des mesures non-fiables, du genre "détecter si je suis au dessus ou en dessous des 50% d'occupation"...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

Discussions similaires

  1. [Batch] [Technique] Processus , Temps , Messages
    Par sokai dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 14/10/2009, 08h40
  2. Récuper le temps processeur d'un processus
    Par KRis dans le forum Langage
    Réponses: 1
    Dernier message: 15/01/2009, 04h33
  3. 4Dclient - Utilisation du temps processeur
    Par clem9 dans le forum 4D
    Réponses: 4
    Dernier message: 19/09/2008, 09h34
  4. [SOLARIS] Consommation processus temps reel
    Par droussa dans le forum Solaris
    Réponses: 2
    Dernier message: 26/06/2007, 18h46
  5. [C#] "Access is denied" pour récupérer le temps processeur
    Par xtream dans le forum Windows Forms
    Réponses: 1
    Dernier message: 22/06/2006, 01h02

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