CPU usage 관련 문의
안녕하세요, 흔히 말하는 CPU usage 관련하여 질문을 하나 드리려고 합니다.
main
for(i = 10000000; i > 0; i--)
nop
와 같은 프로그램을 성능이 높은 컴퓨터(더 높은 클럭)와 성능이 낮은 컴퓨터(더 낮은 클럭)에서 수행한다고 했을때.
다른 프로세스가 전혀 없고 이 프로그램만이 CPU에서 수행되는 유일한 일이라 가정하면,
성능이 높은 컴퓨터에서도 똑같이 CPU 점유율은 100%로 나타나고 성능이 낮은 컴퓨터에서도 CPU 100%으로 나타나지만,
성능이 높은 컴퓨터에서는 프로그램이 더 빨리 종료되고 성능이 낮은 컴퓨터에서는 더 오랜시간 100% CPU usage가
지속되는 것이 맞는 것인가요?
(즉, 성능이 높은 컴퓨터에서는 CPU usage가 50%이고 성능이 낮은 컴퓨터에서는 CPU usage가 100% 인 식이 아니고)
단순하게 성능이 좋은 컴퓨터와 성능이 낮은 컴퓨터의 차이가 시스템 틱 (jiffies) 의 주기가 절대시간으로
더 짧은 것으로 이해를 해도 되는 것인가요?
즉, 1초당 CPU의 usage를 출력하는 프로그램을 생각해 볼 때,
성능이 좋은 컴퓨터는 성능이 상대적으로 낮은 컴퓨터에 비해서 1초당 더 많은 시스템 틱(더 짧은 jiffies)을 가지는 것으로
생각해 볼 수 있는 것인가요?
그리고 CPU 점유율이란 것은 바로 이 초당 발생되는 틱이 idle 테스크가 아닌 실제 일을 하는 테스크에 몇 개가
할당되었는지를 통해서 계산을 해 내는 것인가요?
감사합니다.


대략 말씀하신 것이 맞습니다. CPU 사용률 계산은
대략 말씀하신 것이 맞습니다. CPU 사용률 계산은 아래와 같이 구해집니다.
usage = 100.0 * totalProcessElapsed / totalSystemElapsed
즉, 운영체제와 사용자프로세스와 idle시 소비된 총 시간에서 사용자 프로세스가 실제로 사용한 CPU 시간의 비율로 나타냅니다.
물론 사용자 프로세스가 유저모드와 커널모드에서 사용한 모든 시간을 고려해야합니다.
아래를 참고하시면 아실 수 있을겁니다.
float MediaPresenter::getCPUUsage() { qint64 pid = QApplication::applicationPid(); float usage = 0.0f; uint64_t processKernelNow = 0; uint64_t processUserNow = 0; uint64_t systemKernelNow = 0; uint64_t systemUserNow = 0; uint64_t processKernelElapsed = 0; uint64_t processUserElapsed = 0; uint64_t systemKernelElapsed = 0; uint64_t systemUserElapsed = 0; uint64_t totalProcessElapsed = 0; uint64_t totalSystemElapsed = 0; #ifdef __WIN32__ ULARGE_INTEGER int64; FILETIME dummy; FILETIME processFileTimeKernelNow; FILETIME processFileTimeUserNow; FILETIME systemFileTimeKernelNow; FILETIME systemFileTimeUserNow; HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (GetProcessTimes(pHandle, &dummy, &dummy, &processFileTimeKernelNow, &processFileTimeUserNow) && GetSystemTimes(&dummy, &systemFileTimeKernelNow, &systemFileTimeUserNow)) { int64.LowPart = processFileTimeKernelNow.dwLowDateTime; int64.HighPart = processFileTimeKernelNow.dwHighDateTime; processKernelNow = int64.QuadPart; int64.LowPart = processFileTimeUserNow.dwLowDateTime; int64.HighPart = processFileTimeUserNow.dwHighDateTime; processUserNow = int64.QuadPart; int64.LowPart = systemFileTimeKernelNow.dwLowDateTime; int64.HighPart = systemFileTimeKernelNow.dwHighDateTime; systemKernelNow = int64.QuadPart; int64.LowPart = systemFileTimeUserNow.dwLowDateTime; int64.HighPart = systemFileTimeUserNow.dwHighDateTime; systemUserNow = int64.QuadPart; } if (pHandle) CloseHandle(pHandle); #endif processKernelElapsed = processKernelNow - this->m_detail.lastProcessKernelTime; processUserElapsed = processUserNow - this->m_detail.lastProcessUserTime; systemKernelElapsed = systemKernelNow - this->m_detail.lastSystemKernelTime; systemUserElapsed = systemUserNow - this->m_detail.lastSystemUserTime; totalProcessElapsed = processKernelElapsed + processUserElapsed; totalSystemElapsed = systemKernelElapsed + systemUserElapsed; if (totalSystemElapsed > 0) usage = 100.0f * totalProcessElapsed / totalSystemElapsed; this->m_detail.lastProcessKernelTime = processKernelNow; this->m_detail.lastProcessUserTime = processUserNow; this->m_detail.lastSystemKernelTime = systemKernelNow; this->m_detail.lastSystemUserTime = systemUserNow; return usage; }-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
댓글 달기