From 9abe16788e05af8ba56f37a8a4501d367c9b77fc Mon Sep 17 00:00:00 2001 From: wuhaotian <694496640@qq.com> Date: Thu, 10 Nov 2022 11:59:49 +0800 Subject: [PATCH] Add CPU IPC get and reconstruct llc miss to PerfData --- common/inc/pwrdata.h | 8 ++++++-- common/inc/pwrmsg.h | 2 +- pwrapic/inc/powerapi.h | 2 +- pwrapic/inc/pwrcpu.h | 2 +- pwrapic/src/powerapi.c | 6 +++--- pwrapic/src/pwrcpu.c | 12 +++++------ pwrapic/test/demo_main.c | 32 ++++++++++++----------------- pwrapis/inc/cpuservice.h | 5 ++--- pwrapis/src/cpuservice.c | 43 +++++++++++++++------------------------ pwrapis/src/server.c | 4 ++-- pwrapis/src/taskservice.c | 27 +++++------------------- 11 files changed, 56 insertions(+), 87 deletions(-) diff --git a/common/inc/pwrdata.h b/common/inc/pwrdata.h index 1fbe04f..e33bd73 100644 --- a/common/inc/pwrdata.h +++ b/common/inc/pwrdata.h @@ -55,9 +55,8 @@ enum CpuAttType { }; typedef enum PWR_COM_COL_DATATYPE { - PWR_COM_DATATYPE_LLC_MISS = 1, + PWR_COM_DATATYPE_CPU_PERF = 1, PWR_COM_DATATYPE_CPU_USAGE, - PWR_COM_DATATYPE_CPU_IPC, PWR_COM_DATATYPE_INVALIDE, } PWR_COM_COL_DATATYPE; @@ -103,6 +102,11 @@ typedef struct PWR_CPU_Usage { PWR_CPU_CoreUsage coreUsage[0]; } PWR_CPU_Usage; +typedef struct PWR_CPU_PerfData { + double ipc; + double llcMiss; +} PWR_CPU_PerfData; + /* typedef enum PWR_CPU_FREQ_DRIVER { PWR_CPU_FREQ_DRV_CPPC = 1, // cppc_cpufreq diff --git a/common/inc/pwrmsg.h b/common/inc/pwrmsg.h index ff4d82b..4674ca8 100644 --- a/common/inc/pwrmsg.h +++ b/common/inc/pwrmsg.h @@ -51,7 +51,7 @@ enum OperationType { COM_CALLBACK_DATA, CPU_GET_INFO = 100, CPU_GET_USAGE, - CPU_GET_CACHE_MISS, + CPU_GET_PERF_DATA, CPU_GET_FREQ_ABILITY, CPU_GET_FREQ_GOVERNOR, CPU_SET_FREQ_GOVERNOR, diff --git a/pwrapic/inc/powerapi.h b/pwrapic/inc/powerapi.h index 5e9787f..8c71771 100644 --- a/pwrapic/inc/powerapi.h +++ b/pwrapic/inc/powerapi.h @@ -38,7 +38,7 @@ PWR_API int PWR_DeleteDcTask(PWR_COM_COL_DATATYPE dataType); // CPU PWR_API int PWR_CPU_GetInfo(PWR_CPU_Info *cpuInfo); PWR_API int PWR_CPU_GetUsage(PWR_CPU_Usage *usage, uint32_t bufferSize); -PWR_API int PWR_CPU_GetLlcMissPerIns(double *cacheMiss); +PWR_API int PWR_CPU_GetPerfData(PWR_CPU_PerfData *perfData); PWR_API int PWR_CPU_GetFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize); PWR_API int PWR_CPU_GetFreqGovernor(char gov[], uint32_t size); // len: MAX_ELEMENT_NAME_LEN PWR_API int PWR_CPU_SetFreqGovernor(char gov[]); diff --git a/pwrapic/inc/pwrcpu.h b/pwrapic/inc/pwrcpu.h index 3d21ece..332349c 100644 --- a/pwrapic/inc/pwrcpu.h +++ b/pwrapic/inc/pwrcpu.h @@ -19,7 +19,7 @@ #include "pwrdata.h" int GetCpuInfo(PWR_CPU_Info *cpuInfo); int GetCpuUsage(PWR_CPU_Usage *usage, uint32_t bufferSize); -int GetCpuLlcMissPerIns(double *cacheMiss); +int GetCpuPerfData(PWR_CPU_PerfData *perfData); int GetCpuFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize); int GetCpuFreqGovernor(char gov[], uint32_t size); int SetCpuFreqGovernor(char gov[], uint32_t size); diff --git a/pwrapic/src/powerapi.c b/pwrapic/src/powerapi.c index 65c8eee..ca38202 100644 --- a/pwrapic/src/powerapi.c +++ b/pwrapic/src/powerapi.c @@ -126,12 +126,12 @@ int PWR_CPU_GetUsage(PWR_CPU_Usage *usage, uint32_t bufferSize) return GetCpuUsage(usage, bufferSize); } -PWR_API int PWR_CPU_GetLlcMissPerIns(double *cacheMiss) +PWR_API int PWR_CPU_GetPerfData(PWR_CPU_PerfData *perfData) { CHECK_STATUS(); - CHECK_NULL_POINTER(cacheMiss); + CHECK_NULL_POINTER(perfData); - return GetCpuLlcMissPerIns(cacheMiss); + return GetCpuPerfData(perfData); } int PWR_CPU_GetFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize) diff --git a/pwrapic/src/pwrcpu.c b/pwrapic/src/pwrcpu.c index 6d7c213..13bb56f 100644 --- a/pwrapic/src/pwrcpu.c +++ b/pwrapic/src/pwrcpu.c @@ -62,21 +62,21 @@ int GetCpuUsage(PWR_CPU_Usage *usage, uint32_t bufferSize) return SUCCESS; } -int GetCpuLlcMissPerIns(double *cacheMiss) +int GetCpuPerfData(PWR_CPU_PerfData *perfData) { ReqInputParam input; - input.optType = CPU_GET_CACHE_MISS; + input.optType = CPU_GET_PERF_DATA; input.dataLen = 0; input.data = NULL; RspOutputParam output; - uint32_t size = sizeof(double); + uint32_t size = sizeof(PWR_CPU_PerfData); output.rspBuffSize = &size; - output.rspData = (void *)cacheMiss; + output.rspData = (void *)perfData; int ret = SendReqAndWaitForRsp(input, output); if (ret != SUCCESS) { - PwrLog(ERROR, "GetCpuLlcMissPerIns failed. ret:%d", ret); + PwrLog(ERROR, "GetCpuPerfData failed. ret:%d", ret); } else { - PwrLog(DEBUG, "GetCpuLlcMissPerIns Succeed."); + PwrLog(DEBUG, "GetCpuPerfData Succeed."); } return ret; } diff --git a/pwrapic/test/demo_main.c b/pwrapic/test/demo_main.c index 2cda54d..b8049a5 100644 --- a/pwrapic/test/demo_main.c +++ b/pwrapic/test/demo_main.c @@ -69,10 +69,12 @@ void LogCallback(int level, const char *fmt, va_list vl) void MetaDataCallback(const PWR_COM_CallbackData *callbackData) { + PWR_CPU_PerfData *perfData = NULL; PWR_CPU_Usage *usage = NULL; switch (callbackData->dataType) { - case PWR_COM_DATATYPE_LLC_MISS: - printf("[TASK]Get cache miss data. miss: %f, ctime:%s\n", *(double *)callbackData->data, + case PWR_COM_DATATYPE_CPU_PERF: + perfData = (PWR_CPU_PerfData *)(callbackData->data); + printf("[TASK]Get PERF data. ipc: %f miss: %f, ctime:%s\n", perfData->ipc, perfData->llcMiss, callbackData->ctime); break; case PWR_COM_DATATYPE_CPU_USAGE: @@ -83,9 +85,6 @@ void MetaDataCallback(const PWR_COM_CallbackData *callbackData) printf(" core%d usage: %f\n", usage->coreNum[i].coreNo, usage->coreNum[i].usage); } */ break; - case PWR_COM_DATATYPE_CPU_IPC: - printf("[TASK]Get Ipc. ipc: %f, ctime:%s\n", *(double *)callbackData->data, callbackData->ctime); - break; default: printf("[TASK]Get INVALIDE data.\n"); break; @@ -145,13 +144,13 @@ static void TEST_PWR_CPU_GetUsage(void) free(u); } -// PWR_CPU_GetLlcMissPerIns -static void TEST_PWR_CPU_GetLlcMissPerIns(void) +// PWR_CPU_GetPerfData +static void TEST_PWR_CPU_GetPerfData(void) { int ret; - double miss = 0; - ret = PWR_CPU_GetLlcMissPerIns(&miss); - printf("PWR_CPU_GetLlcMissPerIns ret: %d, LLC misses:%.8f \n", ret, miss); + PWR_CPU_PerfData perfData = {0}; + ret = PWR_CPU_GetPerfData(&perfData); + printf("PWR_CPU_GetPerfData ret: %d, IPC: %.8f LLC misses: %.8f \n", ret, perfData.ipc, perfData.llcMiss); } // PWR_CPU_GetFreqAbility @@ -241,24 +240,19 @@ static void TEST_PWR_COM_DcTaskMgr(void) printf("PWR_SetMetaDataCallback ret: %d\n", ret); PWR_COM_BasicDcTaskInfo task = { 0 }; - task.dataType = PWR_COM_DATATYPE_LLC_MISS; + task.dataType = PWR_COM_DATATYPE_CPU_PERF; task.interval = TASK_INTERNAL; ret = PWR_CreateDcTask(&task); printf("PWR_CreateDcTask. dataType:%d ret: %d\n", task.dataType, ret); task.dataType = PWR_COM_DATATYPE_CPU_USAGE; ret = PWR_CreateDcTask(&task); printf("PWR_CreateDcTask. dataType:%d ret: %d\n", task.dataType, ret); - task.dataType = PWR_COM_DATATYPE_CPU_IPC; - ret = PWR_CreateDcTask(&task); - printf("PWR_CreateDcTask. dataType:%d ret: %d\n", task.dataType, ret); sleep(TASK_RUN_TIME); - ret = PWR_DeleteDcTask(PWR_COM_DATATYPE_LLC_MISS); - printf("PWR_DeleteDcTask. dataType:%d ret: %d\n", PWR_COM_DATATYPE_LLC_MISS, ret); + ret = PWR_DeleteDcTask(PWR_COM_DATATYPE_CPU_PERF); + printf("PWR_DeleteDcTask. dataType:%d ret: %d\n", PWR_COM_DATATYPE_CPU_PERF, ret); ret = PWR_DeleteDcTask(PWR_COM_DATATYPE_CPU_USAGE); printf("PWR_DeleteDcTask. dataType:%d ret: %d\n", PWR_COM_DATATYPE_CPU_USAGE, ret); - ret = PWR_DeleteDcTask(PWR_COM_DATATYPE_CPU_IPC); - printf("PWR_DeleteDcTask. dataType:%d ret: %d\n", PWR_COM_DATATYPE_CPU_IPC, ret); } int main(int argc, const char *args[]) @@ -276,7 +270,7 @@ int main(int argc, const char *args[]) TEST_PWR_CPU_GetUsage(); // PWR_CPU_GetUsage - TEST_PWR_CPU_GetLlcMissPerIns(); + TEST_PWR_CPU_GetPerfData(); // PWR_CPU_GetFreqAbility // TEST_PWR_CPU_GetFreqAbility(); diff --git a/pwrapis/inc/cpuservice.h b/pwrapis/inc/cpuservice.h index 57dde9d..12740aa 100644 --- a/pwrapis/inc/cpuservice.h +++ b/pwrapis/inc/cpuservice.h @@ -19,11 +19,10 @@ void GetCpuinfo(PwrMsg *req); void GetCpuUsage(PwrMsg *req); -void GetLLCMiss(PwrMsg *req); +void GetCpuPerfData(PwrMsg *req); void GetCpuFreq(PwrMsg *req); -int LLCMissRead(double *lm); +int PerfDataRead(PWR_CPU_PerfData *perfData); int CPUUsageRead(PWR_CPU_Usage *rstData, int coreNum); -int CpuIpcRead(double *ipc); void GetCpuFreqGovernor(PwrMsg *req); void SetCpuFreqGovernor(PwrMsg *req); int GetCpuCoreNumber(void); diff --git a/pwrapis/src/cpuservice.c b/pwrapis/src/cpuservice.c index 5b2ed67..030a978 100644 --- a/pwrapis/src/cpuservice.c +++ b/pwrapis/src/cpuservice.c @@ -183,14 +183,14 @@ int CPUUsageRead(PWR_CPU_Usage *rstData, int coreNum) return SUCCESS; } -int LLCMissRead(double *lm) +int PerfDataRead(PWR_CPU_PerfData *perfData) { int m = GetArch(); char *missStr; if (m == AARCH_64) { - missStr = "perf stat -e r0033 -e instructions -a sleep 0.1 &>perf.txt"; + missStr = "perf stat -e r0033 -e instructions -e cycles -a sleep 0.1 &>perf.txt"; } else if (m == X86_64) { - missStr = "perf stat -e LLC-load-misses -e LLC-store-misses -e instructions -a sleep 0.1 &>perf.txt"; + missStr = "perf stat -e LLC-load-misses -e instructions -e cycles -a sleep 0.1 &>perf.txt"; } else { // Add other arch return 1; } @@ -204,6 +204,7 @@ int LLCMissRead(double *lm) int i = 0; unsigned long cacheMiss = 0; unsigned long ins = 0; + unsigned long cycles = 0; while (fgets(buf, sizeof(buf) - 1, fp) != NULL) { if (buf == NULL) { return 1; @@ -211,26 +212,21 @@ int LLCMissRead(double *lm) DeleteChar(buf, '\n'); DeleteChar(buf, ' '); DeleteChar(buf, ','); - if ((strstr(buf, "r0033") != NULL) || (strstr(buf, "LLC-load-misses") != NULL) || - (strstr(buf, "LLC-load-misses") != NULL)) { + if ((strstr(buf, "r0033") != NULL) || (strstr(buf, "LLC-load-misses") != NULL)) { DeleteSubstr(buf, "r0033"); DeleteSubstr(buf, "LLC-load-misses"); - DeleteSubstr(buf, "LLC-store-misses"); cacheMiss += strtoul(buf, NULL, DECIMAL); } else if (strstr(buf, "instructions") != NULL) { DeleteSubstr(buf, "instructions"); ins += strtoul(buf, NULL, DECIMAL); + } else if (strstr(buf, "cycles") != NULL) { + DeleteSubstr(buf, "cycles"); + cycles += strtoul(buf, NULL, DECIMAL); } } - *lm = (double)cacheMiss / ins; + perfData->llcMiss = (double)cacheMiss / ins; + perfData->ipc = (double)ins / cycles; pclose(fp); - return 0; -} - -int CpuIpcRead(double *ipc) -{ - *ipc = 1.0; - // todo: impl get ipc return SUCCESS; } @@ -375,14 +371,7 @@ void GetCpuUsage(PwrMsg *req) return; } Logger(DEBUG, MD_NM_SVR_CPU, "Get GetCpuUsage Req. seqId:%u, sysId:%d", req->head.seqId, req->head.sysId); - PWR_CPU_Info *info = (PWR_CPU_Info *)malloc(sizeof(PWR_CPU_Info)); - if (info == NULL) { - Logger(ERROR, MD_NM_SVR_CPU, "Malloc failed."); - return; - } - CpuInfoRead(info); - int coreNum = info->coreNum; - free(info); + int coreNum = GetCpuCoreNumber(); PWR_CPU_Usage *rstData = malloc(sizeof(PWR_CPU_Usage) + sizeof(PWR_CPU_CoreUsage) * coreNum); if (!rstData) { return; @@ -401,17 +390,17 @@ void GetCpuUsage(PwrMsg *req) } } -void GetLLCMiss(PwrMsg *req) +void GetCpuPerfData(PwrMsg *req) { if (!req) { return; } - Logger(DEBUG, MD_NM_SVR_CPU, "Get Get Cache Miss Req. seqId:%u, sysId:%d", req->head.seqId, req->head.sysId); - double *rstData = malloc(sizeof(double)); + Logger(DEBUG, MD_NM_SVR_CPU, "Get Get Perf Data Req. seqId:%u, sysId:%d", req->head.seqId, req->head.sysId); + PWR_CPU_PerfData *rstData = malloc(sizeof(PWR_CPU_PerfData)); if (!rstData) { return; } - int rspCode = LLCMissRead(rstData); + int rspCode = PerfDataRead(rstData); PwrMsg *rsp = (PwrMsg *)malloc(sizeof(PwrMsg)); if (!rsp) { Logger(ERROR, MD_NM_SVR_CPU, "Malloc failed."); @@ -419,7 +408,7 @@ void GetLLCMiss(PwrMsg *req) return; } bzero(rsp, sizeof(PwrMsg)); - GenerateRspMsg(req, rsp, rspCode, (char *)rstData, sizeof(double)); + GenerateRspMsg(req, rsp, rspCode, (char *)rstData, sizeof(PWR_CPU_PerfData)); if (SendRspMsg(rsp) != SUCCESS) { ReleasePwrMsg(&rsp); } diff --git a/pwrapis/src/server.c b/pwrapis/src/server.c index 126fa65..61d843d 100644 --- a/pwrapis/src/server.c +++ b/pwrapis/src/server.c @@ -326,8 +326,8 @@ static void ProcessReqMsg(PwrMsg *req) case CPU_GET_USAGE: GetCpuUsage(req); break; - case CPU_GET_CACHE_MISS: - GetLLCMiss(req); + case CPU_GET_PERF_DATA: + GetCpuPerfData(req); break; case CPU_GET_INFO: GetCpuinfo(req); diff --git a/pwrapis/src/taskservice.c b/pwrapis/src/taskservice.c index 1e6de65..349242b 100644 --- a/pwrapis/src/taskservice.c +++ b/pwrapis/src/taskservice.c @@ -190,14 +190,14 @@ static PWR_COM_CallbackData *CreateMedataObject(int dataLen, PWR_COM_COL_DATATYP } typedef void (*ActionFunc)(CollTask *, const struct timeval *); -static void TaskProcessLlcMiss(CollTask *task, const struct timeval *startTime) +static void TaskProcessCpuPerf(CollTask *task, const struct timeval *startTime) { - int callbackDataLen = sizeof(PWR_COM_CallbackData) + sizeof(double); + int callbackDataLen = sizeof(PWR_COM_CallbackData) + sizeof(PWR_CPU_PerfData); PWR_COM_CallbackData *callbackData = CreateMedataObject(callbackDataLen, task->dataType); if (!callbackData) { return; } - if (LLCMissRead((double *)callbackData->data) != SUCCESS) { + if (PerfDataRead((PWR_CPU_PerfData *)callbackData->data) != SUCCESS) { free(callbackData); return; } @@ -221,30 +221,13 @@ static void TaskProcessCpuUsage(CollTask *task, const struct timeval *startTime) free(callbackData); } -static void TaskProcessCpuIpc(CollTask *task, const struct timeval *startTime) -{ - int callbackDataLen = sizeof(PWR_COM_CallbackData) + sizeof(double); - PWR_COM_CallbackData *callbackData = CreateMedataObject(callbackDataLen, task->dataType); - if (!callbackData) { - return; - } - if (CpuIpcRead((double *)callbackData->data) != SUCCESS) { - free(callbackData); - return; - } - SendMetadataToSubscribers(task, (char *)callbackData, callbackDataLen, startTime); - free(callbackData); -} - static ActionFunc GetActionByDataType(PWR_COM_COL_DATATYPE dataType) { switch (dataType) { - case PWR_COM_DATATYPE_LLC_MISS: - return TaskProcessLlcMiss; + case PWR_COM_DATATYPE_CPU_PERF: + return TaskProcessCpuPerf; case PWR_COM_DATATYPE_CPU_USAGE: return TaskProcessCpuUsage; - case PWR_COM_DATATYPE_CPU_IPC: - return TaskProcessCpuIpc; default: return NULL; } -- Gitee