1

I am using Win32 x64 Environment

Please go link below too

I have found an answer from this link Collecting CPU Usage of a Process

Under first answer for Windows criteria,you able to see code snippet as below:

double getCurrentValue(){
    FILETIME ftime, fsys, fuser;
    ULARGE_INTEGER now, sys, user;
    double percent;

    GetSystemTimeAsFileTime(&ftime);
    memcpy(&now, &ftime, sizeof(FILETIME));

    GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);
    memcpy(&sys, &fsys, sizeof(FILETIME));
    memcpy(&user, &fuser, sizeof(FILETIME));
    percent = (sys.QuadPart - lastSysCPU.QuadPart) +
        (user.QuadPart - lastUserCPU.QuadPart);
    percent /= (now.QuadPart - lastCPU.QuadPart);
    percent /= numProcessors;
    lastCPU = now;
    lastUserCPU = user;
    lastSysCPU = sys;

    return percent * 100;
}
//--------------------------- FOCUS -----------------------------//
    percent = (sys.QuadPart - lastSysCPU.QuadPart) +(user.QuadPart - lastUserCPU.QuadPart); // ---(1)
    percent /= (now.QuadPart - lastCPU.QuadPart); // ---(2)
    percent /= numProcessors; // --- (3)

As in line (1) assigning ULONGLONG(unsigned long long) to double give compiler warning C4244: conversion from 'ULONGLONG' to 'double', possible loss of data

  • Therefore @Line #(1),(2) & (3) how can we have a guarantee about the value of double precent data?

(Since Ulonglong 64 bit integral data convert to 64bit floating point data)

  • Sometimes this precent value gets value above 100.00 for time stamps as CPU Usage
Buddhika Chaturanga
  • 957
  • 2
  • 14
  • 29
  • 5
    Hard to avoid this. After all, large 64 bit integers can't be represented exactly in a double. Doubles has 53 bit mantissa. But I doubt that is the reason for values greater than 100. You should be able to work out why that happens with some debugging. What debugging have you done? Don't be helpless. This sort of debugging is mechanical and trivially easy. – David Heffernan Nov 17 '17 at 07:41
  • 1
    Normally, when conversion problems could be present, the standard way is to craft code in a way to compute **almost** everything using the largest integer type then before divisions, or multiplications, check for values in range of the float variable. **Remember that a ratio between 2 values V1 and V2 is equal to the ratio between V1/2 and V2/2**. But the 2 halves can be obtained in an integer by simply shifting, and **the loss of 1bit (the lsb in the innteger)** in a `double` range is always negligible. – Frankie_C Nov 17 '17 at 08:20
  • Do you really need fractional percentages? – jwdonahue Nov 17 '17 at 08:25
  • @Frankie This warning concerns the assignment to double of a 64 bit integer. Arithmetic is not relevant to that warning. – David Heffernan Nov 17 '17 at 08:40
  • @jwdonahue yeahp.. I need , I write the double `percent` value in to a text file.noticed some values beyond `100.00` :( @DavidHeffernan – Buddhika Chaturanga Nov 17 '17 at 09:01
  • @DavidHeffernan Math **is** the key. By definition a double cannot host, with full precision, a 64bits integer, meaning that the compiler is always legitimate to trigger the warning, but you **can anyway craft an expression forcing the implicit cast when you're sure that there will be no overflow**. The warning will be in that case harmless. – Frankie_C Nov 17 '17 at 09:52
  • @Frankie_C I already said in the very first comment that a double only has 53 bit mantissa. I was railing against your comment that seemed to implicate the arithmetic as the culprit. But perhaps I just misunderstood you. – David Heffernan Nov 17 '17 at 09:58
  • @BuddhikaChaturanga How is that debugging going? – David Heffernan Nov 17 '17 at 09:58
  • @DavidHeffernan showing some unexpected values.. 100.012 likely values. – Buddhika Chaturanga Nov 17 '17 at 10:02
  • 2
    @All , Any tricky idea if it is exist ..in current computer FPU architecture..`to store maximum value of 64 bit integral type in floating point data type` ,can we treat or reinterpret 64 bit unsigned integral value in to two separate 64 bit floating point data and merge them when we need them in an operation .. – Buddhika Chaturanga Nov 17 '17 at 10:03
  • Don't be helpless. Don't just look at the answers and wonder who they arise. Log the inputs to your calculation, and therefore workout why you get such values. – David Heffernan Nov 17 '17 at 10:03
  • @DavidHeffernan ,`line number (1)` can be suspected.but cannot generate a logic why it's occurring – Buddhika Chaturanga Nov 17 '17 at 10:08
  • @DavidHeffernan Thanks David. The OP must also consider that the absence of the warning, i.e. using only 64bits int's, doesn't mean that the computation cannot overflow. I we assign to a 64bit variable the sum of 2 64bits values we'll get no warning form compiler, but the result could overflow in any case (the sum is bigger that 2^64). The programmer must always check. That's why my solution would have used fixed point arithmetic, performing all calculations using 64bits int multiplied by the requested precision (10 for 1 decimal digit and 100 for 2), then casting the result to ... – Frankie_C Nov 17 '17 at 10:11
  • `double percent = (double)i64_percent/10.0` or `(double)i64_percent/100.0`. – Frankie_C Nov 17 '17 at 10:12
  • @BuddhikaChaturanga Never mind, I don't seem to be making any headway here. – David Heffernan Nov 17 '17 at 10:13
  • @DavidHeffernan what's your suggestion ? – Buddhika Chaturanga Nov 17 '17 at 10:22
  • @BuddhikaChaturanga One tricky idea would be the use of 80bits floating that are no more available under C (in past MS used them for `long double`, but it's no more used for conformity), unless you want use assembler. The point is that **the warning is legal and cannot be avoided**. You, and only you can check your computing flow to be sure that no waste of precision can be present. P.S. there are also 128 bits functions see https://msdn.microsoft.com/en-us/library/windows/desktop/aa383711(v=vs.85).aspx – Frankie_C Nov 17 '17 at 10:22
  • @Frankie_C `long double` :( bad luck with visual compiler - https://msdn.microsoft.com/en-us/library/s3f49ktz.aspx `long double Same as double` damn – Buddhika Chaturanga Nov 17 '17 at 10:26
  • I suggest you do some debugging. But you don't appear to want to. This is to understand why values greater than 100 arise. Do you want to understand that or not? It seems to me that you aren't trying to understand, but instead are flailing around with lots of trial and error and guesswork. Don't waste your own time (and ours) that way. Seek to understand. – David Heffernan Nov 17 '17 at 10:26
  • @DavidHeffernan ,yeah that's what I mentioned you before.while I debug I just noticed that dividing parts `line #2 ` is the point.. generating high values.. – Buddhika Chaturanga Nov 17 '17 at 10:30
  • No, forget it, this isn't going to work out at all. – David Heffernan Nov 17 '17 at 10:31
  • @DavidHeffernan for your infromation I don't want to waste you time .. if you cannot figure it out. just don't answer . i am not forcing anyone.This is for knowledge sharing not to bug fix I know that . `line #2` generating high values because `(now.QuadPart - lastCPU.QuadPart)` cast in to a smaller double value than expected.. therefore whole expression result unexpected higher value. – Buddhika Chaturanga Nov 17 '17 at 10:33
  • I can figure this out no problem. I'm trying to show you how to debug such problems for yourself. Do you want to learn how to? – David Heffernan Nov 17 '17 at 10:45
  • @DavidHeffernan okey teach me... – Buddhika Chaturanga Nov 17 '17 at 11:02
  • https://stackoverflow.com/questions/47345339/how-can-avoid-warning-c4244-conversion-from-ulonglong-to-double-possible-l?noredirect=1#comment81647659_47345339 – David Heffernan Nov 17 '17 at 11:02

1 Answers1

1

Assuming that you call your getCurrentValue function in short intervals you can safely cast values to double. You can also check for extreme case with calls separated by years.

ULONGLONG used = (sys.QuadPart - lastSysCPU.QuadPart) + (user.QuadPart - lastUserCPU.QuadPart);
ULONGLONG elapsed = (now.QuadPart - lastCPU.QuadPart);
if ( elapsed == 0 )
{
    // Now it is imposible, but it could be problem in future :)
    // Do something sane here. For example restart calculation.
}
else
{
    double percent = ( (double)used / (double)elapsed ) / numProcessors * 100.0;
    // Clamp value for rounding errors in our or system code.
    if ( percent > 100.0 )
        percent = 100.0;

    if ( elapsed >= ( 1ull << 53 ) || used >= ( 1ull << 53 ) )
    {
         // Set some flag that result could be not precise.
         // For 'elapsed' this needs 28 years.
         // 'used' could kick earlier: 28/num_processors years.
         // But if you realy need only 4 or 5 digits you can
         // ignore this case.
    }
}
Daniel Sęk
  • 2,504
  • 1
  • 8
  • 17
  • I done exact thing you mentioned earlier except last condition statement .. `if ( elapsed >= ( 1ull << 53 ) || used >= ( 1ull << 53 ) )` ,thanks for the sharing that statement. – Buddhika Chaturanga Nov 20 '17 at 05:38