c++ proc_pid_rusage获得的cpu_time不符合macOS M1芯片的预期

oknwwptz  于 2023-06-25  发布在  Mac
关注(0)|答案(1)|浏览(212)

目前我需要计算macOS平台上某个进程的cpu使用情况(目标进程与当前进程没有直接关系)。我使用proc_pid_rusage API。计算方法是每隔一段时间调用一次,然后计算这段时间的ri_user_time和ri_system_time的差值。以便计算CPU使用率的百分比。
我在非M1芯片的macOS系统上使用过,结果符合预期(基本上和我在活动监视器上看到的一样),但最近我发现在M1芯片的macOS系统上获得的数值很小。例如,我的一个进程消耗了30%以上的cpu(来自活动监视器),但小于1%
我提供了一个demo代码,可以直接创建一个新的项目来运行:

  1. //
  2. // main.cpp
  3. // SimpleMonitor
  4. //
  5. // Created by m1 on 2021/2/23.
  6. //
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <libproc.h>
  10. #include <stdint.h>
  11. #include <iostream>
  12. #include <thread> // std::this_thread::sleep_for
  13. #include <chrono> // std::chrono::seconds
  14. int main(int argc, const char * argv[]) {
  15. // insert code here...
  16. std::cout << "run simple monitor!\n";
  17. // TODO: change process id:
  18. int64_t pid = 12483;
  19. struct rusage_info_v4 ru;
  20. struct rusage_info_v4 ru2;
  21. int64_t success = (int64_t)proc_pid_rusage((pid_t)pid, RUSAGE_INFO_V4, (rusage_info_t *)&ru);
  22. if (success != 0) {
  23. std::cout << "get cpu time fail \n";
  24. return 0;
  25. }
  26. 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;
  27. std::this_thread::sleep_for (std::chrono::seconds(10));
  28. int64_t success2 = (int64_t)proc_pid_rusage((pid_t)pid, RUSAGE_INFO_V4, (rusage_info_t *)&ru2);
  29. if (success2 != 0) {
  30. std::cout << "get cpu time fail \n";
  31. return 0;
  32. }
  33. 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;
  34. int64_t cpu_time = ru2.ri_user_time - ru.ri_user_time + ru2.ri_system_time - ru.ri_system_time;
  35. // percentage:
  36. double cpu_usage = (double)cpu_time / 10 / 1000000000 * 100 ;
  37. std::cout<<pid<<" cpu usage: "<<cpu_usage<<std::endl;
  38. }

这里我想知道我的计算方法是否有问题,如果没有问题,在M1芯片macOS系统上如何处理不准确的结果?

yizd12fk

yizd12fk1#

你必须将CPU使用率乘以某个常数。下面是一些来自diff的代码片段。

  1. #include <mach/mach_time.h>
  2. // ...
  3. mach_timebase_info_data_t sTimebase;
  4. mach_timebase_info(&sTimebase);
  5. timebase_to_ns = (double)sTimebase.numer / (double)sTimebase.denom;
  6. // ...
  7. syscpu.total = task_info.ptinfo.pti_total_system* timebase_to_ns/ 1000000;
  8. usercpu.total = task_info.ptinfo.pti_total_user* timebase_to_ns / 1000000;

相关问题