Total cpu periods

This commit is contained in:
jackun 2020-02-02 02:12:01 +02:00
parent c9e9c2feaf
commit 90416278e0
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3
3 changed files with 81 additions and 63 deletions

View File

@ -28,7 +28,71 @@ static bool starts_with(const std::string& s, const char *t){
return s.rfind(t, 0) == 0;
}
std::vector<int> coreMhz;
void calculateCPUData(CPUData& cpuData,
unsigned long long int usertime,
unsigned long long int nicetime,
unsigned long long int systemtime,
unsigned long long int idletime,
unsigned long long int ioWait,
unsigned long long int irq,
unsigned long long int softIrq,
unsigned long long int steal,
unsigned long long int guest,
unsigned long long int guestnice)
{
// Guest time is already accounted in usertime
usertime = usertime - guest;
nicetime = nicetime - guestnice;
// Fields existing on kernels >= 2.6
// (and RHEL's patched kernel 2.4...)
unsigned long long int idlealltime = idletime + ioWait;
unsigned long long int systemalltime = systemtime + irq + softIrq;
unsigned long long int virtalltime = guest + guestnice;
unsigned long long int totaltime = usertime + nicetime + systemalltime + idlealltime + steal + virtalltime;
// Since we do a subtraction (usertime - guest) and cputime64_to_clock_t()
// used in /proc/stat rounds down numbers, it can lead to a case where the
// integer overflow.
#define WRAP_SUBTRACT(a,b) (a > b) ? a - b : 0
cpuData.userPeriod = WRAP_SUBTRACT(usertime, cpuData.userTime);
cpuData.nicePeriod = WRAP_SUBTRACT(nicetime, cpuData.niceTime);
cpuData.systemPeriod = WRAP_SUBTRACT(systemtime, cpuData.systemTime);
cpuData.systemAllPeriod = WRAP_SUBTRACT(systemalltime, cpuData.systemAllTime);
cpuData.idleAllPeriod = WRAP_SUBTRACT(idlealltime, cpuData.idleAllTime);
cpuData.idlePeriod = WRAP_SUBTRACT(idletime, cpuData.idleTime);
cpuData.ioWaitPeriod = WRAP_SUBTRACT(ioWait, cpuData.ioWaitTime);
cpuData.irqPeriod = WRAP_SUBTRACT(irq, cpuData.irqTime);
cpuData.softIrqPeriod = WRAP_SUBTRACT(softIrq, cpuData.softIrqTime);
cpuData.stealPeriod = WRAP_SUBTRACT(steal, cpuData.stealTime);
cpuData.guestPeriod = WRAP_SUBTRACT(virtalltime, cpuData.guestTime);
cpuData.totalPeriod = WRAP_SUBTRACT(totaltime, cpuData.totalTime);
#undef WRAP_SUBTRACT
cpuData.userTime = usertime;
cpuData.niceTime = nicetime;
cpuData.systemTime = systemtime;
cpuData.systemAllTime = systemalltime;
cpuData.idleAllTime = idlealltime;
cpuData.idleTime = idletime;
cpuData.ioWaitTime = ioWait;
cpuData.irqTime = irq;
cpuData.softIrqTime = softIrq;
cpuData.stealTime = steal;
cpuData.guestTime = virtalltime;
cpuData.totalTime = totaltime;
if (cpuData.totalPeriod == 0)
return;
float total = (float)cpuData.totalPeriod;
float v[4];
v[0] = cpuData.nicePeriod * 100.0f / total;
v[1] = cpuData.userPeriod * 100.0f / total;
/* if not detailed */
v[2] = cpuData.systemAllPeriod * 100.0f / total;
v[3] = (cpuData.stealPeriod + cpuData.guestPeriod) * 100.0f / total;
//cpuData.percent = std::clamp(v[0]+v[1]+v[2]+v[3], 0.0f, 100.0f);
cpuData.percent = std::min(std::max(v[0]+v[1]+v[2]+v[3], 0.0f), 100.0f);
}
CPUStats::CPUStats()
{
@ -106,6 +170,7 @@ bool CPUStats::UpdateCPUData()
} else if (!ret && sscanf(line.c_str(), "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu",
&usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice) == 10) {
ret = true;
calculateCPUData(m_cpuDataTotal, usertime, nicetime, systemtime, idletime, ioWait, irq, softIrq, steal, guest, guestnice);
} else if (sscanf(line.c_str(), "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu",
&cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice) == 11) {
@ -123,58 +188,9 @@ bool CPUStats::UpdateCPUData()
}
CPUData& cpuData = m_cpuData[cpuid];
// Guest time is already accounted in usertime
usertime = usertime - guest;
nicetime = nicetime - guestnice;
// Fields existing on kernels >= 2.6
// (and RHEL's patched kernel 2.4...)
unsigned long long int idlealltime = idletime + ioWait;
unsigned long long int systemalltime = systemtime + irq + softIrq;
unsigned long long int virtalltime = guest + guestnice;
unsigned long long int totaltime = usertime + nicetime + systemalltime + idlealltime + steal + virtalltime;
// Since we do a subtraction (usertime - guest) and cputime64_to_clock_t()
// used in /proc/stat rounds down numbers, it can lead to a case where the
// integer overflow.
#define WRAP_SUBTRACT(a,b) (a > b) ? a - b : 0
cpuData.userPeriod = WRAP_SUBTRACT(usertime, cpuData.userTime);
cpuData.nicePeriod = WRAP_SUBTRACT(nicetime, cpuData.niceTime);
cpuData.systemPeriod = WRAP_SUBTRACT(systemtime, cpuData.systemTime);
cpuData.systemAllPeriod = WRAP_SUBTRACT(systemalltime, cpuData.systemAllTime);
cpuData.idleAllPeriod = WRAP_SUBTRACT(idlealltime, cpuData.idleAllTime);
cpuData.idlePeriod = WRAP_SUBTRACT(idletime, cpuData.idleTime);
cpuData.ioWaitPeriod = WRAP_SUBTRACT(ioWait, cpuData.ioWaitTime);
cpuData.irqPeriod = WRAP_SUBTRACT(irq, cpuData.irqTime);
cpuData.softIrqPeriod = WRAP_SUBTRACT(softIrq, cpuData.softIrqTime);
cpuData.stealPeriod = WRAP_SUBTRACT(steal, cpuData.stealTime);
cpuData.guestPeriod = WRAP_SUBTRACT(virtalltime, cpuData.guestTime);
cpuData.totalPeriod = WRAP_SUBTRACT(totaltime, cpuData.totalTime);
#undef WRAP_SUBTRACT
cpuData.userTime = usertime;
cpuData.niceTime = nicetime;
cpuData.systemTime = systemtime;
cpuData.systemAllTime = systemalltime;
cpuData.idleAllTime = idlealltime;
cpuData.idleTime = idletime;
cpuData.ioWaitTime = ioWait;
cpuData.irqTime = irq;
cpuData.softIrqTime = softIrq;
cpuData.stealTime = steal;
cpuData.guestTime = virtalltime;
cpuData.totalTime = totaltime;
calculateCPUData(cpuData, usertime, nicetime, systemtime, idletime, ioWait, irq, softIrq, steal, guest, guestnice);
cpuid = -1;
float total = (float)(cpuData.totalPeriod == 0 ? 1 : cpuData.totalPeriod);
float v[4];
v[0] = cpuData.nicePeriod * 100.0f / total;
v[1] = cpuData.userPeriod * 100.0f / total;
/* if not detailed */
v[2] = cpuData.systemAllPeriod * 100.0f / total;
v[3] = (cpuData.stealPeriod + cpuData.guestPeriod) * 100.0f / total;
cpuData.percent = std::min(std::max(v[0]+v[1]+v[2]+v[3], 0.0f), 100.0f);
} else {
break;
}
@ -186,22 +202,18 @@ bool CPUStats::UpdateCPUData()
}
bool CPUStats::UpdateCoreMhz() {
coreMhz.clear();
FILE *cpuInfo = fopen(PROCCPUINFOFILE, "r");
char line[256];
m_coreMhz.clear();
std::ifstream cpuInfo(PROCCPUINFOFILE);
std::string row;
int i = 0;
while (fgets(line, sizeof(line), cpuInfo)) {
while (std::getline(cpuInfo, row)) {
CPUData& cpuData = m_cpuData[i];
std::string row;
row = line;
if (row.find("MHz") != std::string::npos){
row = std::regex_replace(row, std::regex(R"([^0-9.])"), "");
cpuData.mhz = stoi(row);
i++;
}
}
fclose(cpuInfo);
return true;
}

View File

@ -48,9 +48,14 @@ public:
const std::vector<CPUData>& GetCPUData() const {
return m_cpuData;
}
const CPUData& GetCPUDataTotal() const {
return m_cpuDataTotal;
}
private:
unsigned long long int m_boottime = 0;
std::vector<CPUData> m_cpuData;
CPUData m_cpuDataTotal {};
std::vector<int> m_coreMhz;
double m_cpuPeriod = 0;
bool m_updatedCPUs = false; // TODO use caching or just update?
bool m_inited = false;

View File

@ -909,12 +909,13 @@ static void snapshot_swapchain_frame(struct swapchain_data *data)
if (capture_begin ||
elapsed >= instance_data->params.fps_sampling_period) {
cpuStats.UpdateCPUData();
int i = 0;
//int i = 0;
cpuLoadLog = 0;
for (const CPUData &cpuData : cpuStats.GetCPUData())
cpuLoadLog += cpuData.percent;
//for (const CPUData &cpuData : cpuStats.GetCPUData())
// cpuLoadLog += cpuData.percent;
cpuLoadLog = cpuLoadLog / cpuStats.GetCPUData().size();
//cpuLoadLog = cpuLoadLog / cpuStats.GetCPUData().size();
cpuLoadLog = cpuStats.GetCPUDataTotal().percent;
pthread_create(&cpuInfoThread, NULL, &cpuInfo, NULL);
// get gpu usage