[Linux/Android] CPU Usage (사용량) 계산 방법

Application의 CPU Usage (사용량)을 계산하는 방법이 궁금하여 인터넷에서 검색한 결과를 정리해보았다. 물론 top, htop과 같은 명령어를 사용하면 이 모든 것을 할 필요가 없다. 먼저 Application의 PID (Process ID)를 정보가 필요하다. 예를 들어 Application의 이름이 co.kr.mkblog.text라고 하면 “pidof” 명령어를 사용하여 예제 Application의 PID를 확인 할 수 있다. Android ADB와 Linux에서 아래 명령어를 입력하면 Application의 PID 번호를 Output으로 출력한다.

  • pidof co.kr.mkblog.test

보통 1개의 PID 번호만 출력이 되는데 간혹 2개 이상의 PID가 출력되는 경우가 있다. 보통 제일 앞에 출력되는 PID의 CPU Usage가 동시에 출력되는 다른 PID 번호의 CPU Usage보다 높은 관계로 처음 PID를 기준으로 CPU Usage를 계산하면 되는 것 같다.

CPU Usage 계산을 위해서는 아래의 정보들이 필요하다. #Number output의 의미는 Number에 출력되는 Output을 의미한다. 보통 Space로 분리되어 출력되며 1부터 시작한다. Python을 사용해서 Input을 받아오는 경우 #0부터 시작하는 관계로 정리된 값에 1을 빼면 된다.

  • 시스템이 켜져있던 시간 (uptime of the system) (upTime): /proc/uptime [#1 output]
  • User 코드 실행시간 (CPU time spent in user code) (uTime): /proc/[PID]/stat [#14 output]
  • Kernel 코드 실행시간 (CPU time spent in kernel code) (sTime): /proc/[PID]/stat [#15 output]
  • Children CPU가 User 코드를 실행하는 동안 대기한 시간 (Waited-for children’s CPU time spent in user code) (cuTime): /proc/[PID]/stat [#16 output]
  • Children CPU가 Kernel 코드를 실행사는 동안 대기한 시간 (Waited-for children’s CPU time spent in kernel code) (csTime): /proc/[PID]/stat [#17 output]
  • Process (Application)가 시작한 시간 (Time when the process started) (startTime): /proc/[PID]/stat [#22 output]

/proc/[PID]/stat 에 출력되는 Time 모두 Clock Tick 단위이다. 위 정보를 이용하여 CPU Usage를 계산하면 된다.

먼저 Process(프로세서)가 명령어를 연산한 시간을 계산한다. (코드(?)를 실행 시간이 더 정확한 표현인지 모르겠다)

  • totalTime = uTime + sTime

만약 Child (Children) Process의 명령어 계산 시간을 포함하고 싶으면 아래와 같이 명령어 연산 시간을 계산한다.

  • totalTime = uTime + sTime + cuTime + csTime

다음은 Process가 생성되어 있었던 시간(Duration)을 계산한다. 여기서 말하는 Hertz는 Linux Kernel Clock Frequency를 의미한다. 보통 Arm을 사용하는 디바이스의 경우 Hertz 값은 100이고, Intel CPU를 사용하는 경우 Hertz는 1000이라고 한다.

  • processUpTime = upTime – (startTime/Hertz) = upTime – (startTime/100) | upTime – (startTime/1000)

마지막으로 CPU Usage를 계산한다. 계산식은 아래와 같다. 아래 식은 프로세서가 생성된 이후의 CPU Usage를 계산하는 것이다. 결과적으로 Application 실행 후 평균 CPU Usage를 계산한다.

  • cpuUsage = 100 * ((totalTime/Hertz) / processUpTime)

만약 Process 생성 이후 부터 평균 CPU Usage가 아니라 특정 시간 단위로 CPU Usage를 계산하고 싶다면 totalTime과 upTime의 시간 차이로 계산을 하면된다. 계산 방법을 아래와 같다.

  • upTimeDiff = current_upTime – previous_upTime //MK: 프로세서가 실행된 시간의 차이 계산
  • totalTimeDiff = current_totalTime – previous_totalTime //MK: 코드가 실행된 시간 차이 계산
  • cpuUsage = 100 * ((totalTimeDiff/Hertz) / upTimeDiff)

아래 코드는 Python을 사용하여 대략 1초에 한 번씩 CPU Usage를 계산하는 코드이다. Window의 경우 ADB Shell이 Daemon을 사용하여 실행되는 것 같다. 그래서  sleep 1로 하여도 대략 3초에 한 번씩 CPU Usage를 계산한다. Python 대신 bash를 사용하는 경우 대략 0.1초 정도의 Delay만 발생한다.

#MK: Measuring CPU Usage
import os
import time

#MK: Getting PID
mkPackageName = "co.kr.mkblog.test"
mkPidCmd = "adb shell pidof " + mkPackageName
mkTmp = os.popen(mkPidCmd).read()
mkTmp = mkTmp.split(" ")
mkPid = mkTmp[0].replace("\n", "")

#MK: Getting Basic Info
mkProcPath = "/proc/" + mkPid + "/stat"
mkUpTimeCmd = "adb shell cat /proc/uptime"
mkUSTimeCmd = "adb shell cat " + mkProcPath

mkUSTimeList = os.popen(mkUSTimeCmd).read().split(" ")
mkUSTime = float(mkUSTimeList[13]) + float(mkUSTimeList[14])
mkStartTime = float(mkUSTimeList[21])

mkUpTimeList = os.popen(mkUpTimeCmd).read().split(" ")
mkUpTime = float(mkUpTimeList[0])

#MK: Calculate CPU Usage for Every 1 Second (Not include children waiting time)
while True:
    mkUpTimeList = os.popen(mkUpTimeCmd).read().split(" ")
    mkUSTimeList = os.popen(mkUSTimeCmd).read().split(" ")
    mkLongTermCpuUsage = 100 * ((float(mkUSTimeList[13]) + float(mkUSTimeList[14]))/100)/(float(mkUpTimeList[0])  - (mkStartTime/100))
    mkShortTermCpuUsage = 100 * (((float(mkUSTimeList[13]) + float(mkUSTimeList[14]) - mkUSTime))/100)/((float(mkUpTimeList[0]) - mkUpTime))
    #MK: Save for Short Term CPU Usage
    mkUSTime = float(mkUSTimeList[13]) + float(mkUSTimeList[14])
    mkUpTime = float(mkUpTimeList[0])
    #MK: Usually First CPU Usage is Incorrect Value
    print("Long Term: " + str(mkLongTermCpuUsage) + ", Short Term: " + str(mkShortTermCpuUsage))
    time.sleep(1)

출처

  1. https://stackoverflow.com/questions/31224313/calculating-cpu-usage-of-a-process-in-android
  2. https://stackoverflow.com/questions/16726779/how-do-i-get-the-total-cpu-usage-of-an-application-from-proc-pid-stat

Leave a Comment