The cpu_time obtained by proc_pid_rusage does not meet expectations on the macOS M1 chip

  apple-m1, c++, macos

At present, I need to calculate the cpu usage of a certain process on the macOS platform (the target process is not directly related to the current process). I use the proc_pid_rusage API. The calculation method is to call it every once in a while, and then calculate this section The difference between ri_user_time and ri_system_time of the time. So as to calculate the percentage of cpu usage.

I used it on a macOS system with non-M1 chip, and the results were in line with expectations (basically the same as what I saw on the activity monitor), but recently I found that the value obtained on the macOS system with the M1 chip is small. For example, one of my processes that consumes 30+% of the cpu(from activity monitor) is less than 1%.

I provide a demo code, you can directly create a new project to run:

//
//  main.cpp
//  SimpleMonitor
//
//  Created by m1 on 2021/2/23.
//
#include <stdio.h>
#include <stdlib.h>
#include <libproc.h>
#include <stdint.h>
#include <iostream>
#include <thread>         // std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "run simple monitor!n";
    
    // TODO: change process id:
    int64_t pid = 12483;

    struct rusage_info_v4 ru;
    struct rusage_info_v4 ru2;

    int64_t success = (int64_t)proc_pid_rusage((pid_t)pid, RUSAGE_INFO_V0, (rusage_info_t *)&ru);
    
    if (success != 0) {
        std::cout << "get cpu time fail n";
        return 0;
    }
    
    std::cout<<"getProcessPerformance, pid=" + std::to_string(pid) + " ru.ri_user_time=" + std::to_string(ru.ri_user_time) + " ru.ri_system_time=" + std::to_string(ru.ri_system_time)<<std::endl;

    std::this_thread::sleep_for (std::chrono::seconds(10));
    
    int64_t success2 = (int64_t)proc_pid_rusage((pid_t)pid, RUSAGE_INFO_V0, (rusage_info_t *)&ru2);
    
    if (success2 != 0) {
        std::cout << "get cpu time fail n";
        return 0;
    }

    std::cout<<"getProcessPerformance, pid=" + std::to_string(pid) + " ru2.ri_user_time=" + std::to_string(ru2.ri_user_time) + " ru2.ri_system_time=" + std::to_string(ru2.ri_system_time)<<std::endl;
    
    int64_t cpu_time = ru2.ri_user_time - ru.ri_user_time + ru2.ri_system_time - ru.ri_system_time;

    // percentage:
    double cpu_usage = (double)cpu_time / 10 / 1000000000 * 100 ;
    
    std::cout<<pid<<" cpu usage: "<<cpu_usage<<std::endl;

}

Here I want to know whether there is a problem with my calculation method, if there is no problem, how can I handle the inaccurate results on the M1 chip macOS system?

Source: Windows Questions C++

LEAVE A COMMENT