!1593 添加命令行采集GPU Counter

Merge pull request !1593 from 牛国亮/master
This commit is contained in:
openharmony_ci 2024-05-13 06:38:55 +00:00 committed by Gitee
commit 1f0fd81411
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 233 additions and 63 deletions

View File

@ -28,13 +28,25 @@ namespace OHOS {
namespace SmartPerf {
const long long WAIT_EXIT_TIME = 500;
const int ERROR_CODE_NEGATIVE_TWO = -2;
const int ERROR_CODE_NEGATIVE_THREE = -3;
const int ERROR_CODE_NEGATIVE_FOUR = -4;
GpuCounter::GpuCounter()
{
originalEP = GetPerm();
LOGI("original execute permissions(%d)", (int)originalEP);
}
std::map<std::string, std::string> GpuCounter::ItemData()
{
std::map<std::string, std::string> result;
isStop = true;
if (initCheckPath == "/data/local/tmp/" && (gcStatus == GC_START || gcStatus == GC_INIT) && (!initMap.empty())) {
result.insert(initMap.begin(), initMap.end());
initMap.clear();
return result;
}
gcStatus = GC_STOP;
KillCounter();
std::this_thread::sleep_for(std::chrono::microseconds(WAIT_EXIT_TIME));
@ -44,8 +56,14 @@ std::map<std::string, std::string> GpuCounter::ItemData()
std::string outStr;
std::string newFileName = constOutDestCVSPrefix + "_" + std::to_string(SPUtils::GetCurTime()) + ".csv";
std::string mvCmd = constMvFile + constOutSourCVSFile + " " + sandBoxPath + newFileName;
std::cout << "FileAccess mvCmd" << mvCmd << std::endl;
SPUtils::LoadCmd(mvCmd, outStr);
LOGI("ItemData new file name(%s)", newFileName.c_str());
if (sandBoxPath != "/data/local/tmp/" && (!isSandBoxWrite)) {
SetPerm(EP_PERMISSIVE);
SPUtils::LoadCmd(mvCmd, outStr);
SetPerm(EP_ENFORCING);
} else {
SPUtils::LoadCmd(mvCmd, outStr);
}
fileList.push_back(newFileName);
}
@ -67,6 +85,33 @@ std::map<std::string, std::string> GpuCounter::ItemData()
return result;
}
int GpuCounter::CheckResources(const std::string &packageName, std::string &errorInfo)
{
std::string result;
SPUtils::LoadCmd(constCheckProductInfo, result);
if (result.empty() || result.find(constProductInfo) == std::string::npos) {
errorInfo = "Non Hisilicon chips";
return ERROR_CODE_NEGATIVE_FOUR;
}
if ((!SPUtils::FileAccess(constV2File)) || (!SPUtils::FileAccess(constExecFile)) ||
(!SPUtils::FileAccess(constConfigFile)) || (!SPUtils::FileAccess(constLibFile))) {
errorInfo = "Missing dependency files such as counters_collector";
return -1;
}
if (packageName.empty()) {
errorInfo = "package name is empty";
return ERROR_CODE_NEGATIVE_TWO;
}
if (packageName == "/data/local/tmp/") {
sandBoxPath = packageName;
} else {
sandBoxPath = constSandBoxPath + packageName + constSandBoxFile;
}
return 0;
}
int GpuCounter::Init(const std::string &packageName, std::map<std::string, std::string> &retMap)
{
@ -74,37 +119,20 @@ int GpuCounter::Init(const std::string &packageName, std::map<std::string, std::
std::string result;
std::string errorInfo;
Rest();
do {
SPUtils::LoadCmd(constCheckProductInfo, result);
if (result.empty() || result.find(constProductInfo) == std::string::npos) {
errorInfo = "Non Hisilicon chips";
ret = ERROR_CODE_NEGATIVE_FOUR;
break;
}
if ((!SPUtils::FileAccess(constV2File)) || (!SPUtils::FileAccess(constExecFile)) ||
(!SPUtils::FileAccess(constConfigFile)) || (!SPUtils::FileAccess(constLibFile))) {
errorInfo = "Missing dependency files such as counters_collector";
ret = -1;
break;
}
if (packageName.empty()) {
errorInfo = "package name is empty";
ret = ERROR_CODE_NEGATIVE_TWO;
break;
}
sandBoxPath = constSandBoxPath + packageName + constSandBoxFile;
if (access(sandBoxPath.c_str(), W_OK) == -1) { // Determine whether SandBox can be written
errorInfo = "unable to access sandbox path(" + sandBoxPath + ")";
ret = ERROR_CODE_NEGATIVE_THREE;
break;
}
} while (false);
ret = CheckResources(packageName, errorInfo);
if (ret != 0) {
retMap["gpu_counter"] = "false";
retMap["error"] = errorInfo;
initMap.insert(retMap.begin(), retMap.end());
LOGE("%s", errorInfo.c_str());
return ret;
}
initCheckPath = packageName;
if (access(sandBoxPath.c_str(), W_OK) == 0) {
isSandBoxWrite = true;
}
SPUtils::LoadCmd(constAddPermissionsCounter, result);
ret = Start();
if (ret == 0) {
@ -115,27 +143,32 @@ int GpuCounter::Init(const std::string &packageName, std::map<std::string, std::
retMap["error"] = errorInfo;
LOGE("%s", errorInfo.c_str());
}
initMap.insert(retMap.begin(), retMap.end());
return ret;
}
void GpuCounter::Rest()
{
isStop = false;
std::string result;
gcStatus = GC_INIT;
fileList.clear();
startCaptureTime = 0;
KillCounter(); // counters_collector if runing kill
if (SPUtils::FileAccess(constOutSourCVSFile)) {
std::string result;
SPUtils::LoadCmd(constRmCsv, result); // clear history files
}
sandBoxPath = "";
initCheckPath = "";
}
int GpuCounter::Start()
{
int ret = -1;
gcStatus = GC_START;
captureDuration = GetCounterDuration();
std::cout << "captureDuration" << captureDuration << std::endl;
LOGI("Start captureDuration(%lld)", captureDuration);
if (captureDuration <= 0) {
captureDuration = constDefaultCaptureDuration;
LOGW("read config duration failed,load default(%ll)", captureDuration);
@ -155,7 +188,7 @@ int GpuCounter::Start()
void GpuCounter::Check()
{
if (isStop) {
if (gcStatus != GC_START) {
return;
}
@ -167,19 +200,28 @@ void GpuCounter::Check()
return;
}
std::cout << " GpuCounter::Check diff > captureDuration diffvalue" << diff << std::endl;
LOGI("GpuCounter::Check diff(%lld)", diff);
std::vector<std::string> pidList;
GetCounterId(pidList);
if (!pidList.empty()) { // GPU process did not exit
return;
}
std::string result;
std::string newFileName = constOutDestCVSPrefix + "_" + std::to_string(nowTime) + ".csv";
std::string mvCmd = constMvFile + constOutSourCVSFile + " " + sandBoxPath + newFileName;
SPUtils::LoadCmd(mvCmd, result);
fileList.push_back(newFileName);
std::cout << " new file name=" << newFileName << std::endl;
if (SPUtils::FileAccess(constOutSourCVSFile)) {
std::string result;
std::string newFileName = constOutDestCVSPrefix + "_" + std::to_string(nowTime) + ".csv";
std::string mvCmd = constMvFile + constOutSourCVSFile + " " + sandBoxPath + newFileName;
if (sandBoxPath != "/data/local/tmp/" && (!isSandBoxWrite)) {
SetPerm(EP_PERMISSIVE);
SPUtils::LoadCmd(mvCmd, result);
SetPerm(EP_ENFORCING);
} else {
SPUtils::LoadCmd(mvCmd, result);
}
fileList.push_back(newFileName);
LOGI("new file name(%s)", newFileName.c_str());
}
Start();
@ -191,11 +233,9 @@ void GpuCounter::GetCounterId(std::vector<std::string> &pidList)
{
std::string result;
std::cout << "GetCounterId constGetCounterId=" << constGetCounterId << std::endl;
pidList.clear();
SPUtils::LoadCmd(constGetCounterId, result);
SPUtils::StrSplit(result, " ", pidList);
std::cout << "GetCounterId end result=" << result << std::endl;
return;
}
@ -205,16 +245,13 @@ void GpuCounter::KillCounter()
std::vector<std::string> pidList;
std::string result;
std::cout << "KillCounter start" << std::endl;
GetCounterId(pidList);
for (auto it = pidList.begin(); pidList.end() != it; ++it) {
std::string killStr = constKillProcess + *it;
std::cout << "KillCounter killStr" << killStr << std::endl;
result.clear();
SPUtils::LoadCmd(killStr, result);
}
std::cout << "KillCounter end" << std::endl;
return;
}
@ -273,5 +310,35 @@ int GpuCounter::Capture()
{
return system(constCmd.c_str());
}
GpuCounter::ExecutePermissions GpuCounter::GetPerm()
{
ExecutePermissions ep = EP_INVALID;
std::string result;
SPUtils::LoadCmd("getenforce", result);
if (result == "Permissive") {
ep = EP_PERMISSIVE;
} else if (result == "Enforcing") {
ep = EP_ENFORCING;
}
return ep;
}
void GpuCounter::SetPerm(ExecutePermissions code)
{
if (!(code == EP_ENFORCING || code == EP_PERMISSIVE)) {
return;
}
if (originalEP == EP_PERMISSIVE) {
return;
}
std::string result;
std::string cmd = "setenforce " + std::to_string(int(code));
SPUtils::LoadCmd(cmd, result);
return;
}
}
}

View File

@ -25,6 +25,19 @@
namespace OHOS {
namespace SmartPerf {
class GpuCounter : public SpProfiler {
public:
enum GcStatus {
GC_INIT = 0,
GC_START,
GC_STOP,
};
enum ExecutePermissions {
EP_INVALID = -1,
EP_PERMISSIVE = 0,
EP_ENFORCING = 1,
};
public:
std::map<std::string, std::string> ItemData() override;
@ -34,6 +47,11 @@ public:
return instance;
}
GcStatus GetStatus()
{
return gcStatus;
}
// -3 sandbox path invalid, -2 package name error -1 dependency file not detected
int Init(const std::string &packageName, std::map<std::string, std::string> &retMap);
void Rest();
@ -43,16 +61,23 @@ public:
long long GetCounterDuration();
private:
int CheckResources(const std::string &packageName, std::string &errorInfo);
void GetCounterId(std::vector<std::string> &pidList);
void KillCounter();
int Capture();
void SetPerm(ExecutePermissions code);
ExecutePermissions GetPerm();
private:
bool isStop = false;
bool isSandBoxWrite = false;
ExecutePermissions originalEP = EP_INVALID;
GcStatus gcStatus = GC_INIT;
long long startCaptureTime = 0;
long long captureDuration = 0;
std::vector<std::string> fileList;
std::string sandBoxPath;
std::string initCheckPath;
std::map<std::string, std::string> initMap;
private:
const long long constDefaultCaptureDuration = 5000; // Unit ms
@ -60,7 +85,7 @@ private:
const std::string constMvFile = "mv -f ";
const std::string constKillProcess = "kill -9 ";
const std::string constGetCounterId = "pidof counters_collector";
const std::string constRmCsv = "rm /data/local/tmp/gpu_conter.csv";
const std::string constRmCsv = "rm /data/local/tmp/gpu_counter.csv";
const std::string constAddPermissionsCounter = "chmod 777 /bin/counters_collector";
const std::string constCmd =
"LD_LIBRARY_PATH=/bin/ /bin/counters_collector /bin/config.txt &";
@ -78,7 +103,7 @@ private:
const std::string constProductInfo = "Mate 60 Pro";
private:
GpuCounter() {};
GpuCounter();
GpuCounter(const GpuCounter &);
GpuCounter &operator = (const GpuCounter &);
};

View File

@ -92,6 +92,7 @@ enum class CommandType {
CT_FL,
CT_FTL,
CT_M,
CT_GC,
};
enum class CommandHelp {
HELP,
@ -121,6 +122,7 @@ const std::unordered_map<std::string, CommandType> COMMAND_MAP = {
{ std::string("-fl"), CommandType::CT_FL },
{ std::string("-ftl"), CommandType::CT_FTL },
{ std::string("-m"), CommandType::CT_M },
{ std::string("-gc"), CommandType::CT_GC },
};
const std::unordered_map<CommandType, std::string> COMMAND_MAP_REVERSE = {
@ -145,6 +147,7 @@ const std::unordered_map<CommandType, std::string> COMMAND_MAP_REVERSE = {
{ CommandType::CT_FL, std::string("-fl") },
{ CommandType::CT_FTL, std::string("-ftl") },
{ CommandType::CT_M, std::string("-m") },
{ CommandType::CT_GC, std::string("-gc") },
};

View File

@ -19,6 +19,7 @@
#include <iostream>
#include <vector>
#include "common.h"
#include "sp_utils.h"
namespace OHOS {
namespace SmartPerf {
@ -49,6 +50,7 @@ public:
" -OUT set csv output path.\n"
" -d get device DDR information \n"
" -m get other memory \n"
" -gc get CPU counter,output in file format at '/data/local/tmp/' \n"
"example:\n"
"SP_daemon -N 20 -c -g -t -p -r -m -net -snapshot -d \n"
"SP_daemon -N 20 -PKG ohos.samples.ecg -c -g -t -p -f -r -m -net -snapshot -d \n"
@ -65,6 +67,7 @@ public:
std::string ExecCommand();
void HelpCommand(CommandHelp type) const;
void HandleCommand(std::string argStr, const std::string &argStr1);
int GetItemInfo(std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> &spMap);
// 采集次数
int num = 0;
// 包名

View File

@ -25,6 +25,7 @@ public:
static void SetProfilerLayer(const std::string &layer);
static void SetByTrace(std::string message);
static SpProfiler *GetCmdProfilerItem(CommandType commandType, bool cmdFlag);
static SpProfiler *GetCmdProfilerItemContinue(CommandType commandType, bool cmdFlag);
};
}
}

View File

@ -121,6 +121,7 @@ void SmartPerfCommand::HandleCommand(std::string argStr, const std::string &argS
case CommandType::CT_SNAPSHOT:
case CommandType::CT_M:
case CommandType::CT_HW:
case CommandType::CT_GC:
configs.push_back(argStr);
break;
default:
@ -129,35 +130,66 @@ void SmartPerfCommand::HandleCommand(std::string argStr, const std::string &argS
}
}
int SmartPerfCommand::GetItemInfo(std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> &spMap)
{
int rc = 0;
std::string errInfo;
for (size_t j = 0; j < configs.size(); j++) {
std::string curParam = configs[j];
SpProfiler *profiler = SpProfilerFactory::GetCmdProfilerItem(COMMAND_MAP.at(curParam), true);
if (profiler != nullptr) {
std::map<std::string, std::string> data = profiler->ItemData();
spMap.insert(data.cbegin(), data.cend());
auto cit = data.find("gpu_counter");
if (cit == data.end()) {
continue;
}
if (cit->second == "true") {
rc = 1;
} else {
cit = data.find("error");
errInfo = "gpu_counter error:";
errInfo += (cit != data.end()) ? cit->second : "run failed";
break;
}
}
}
if (!errInfo.empty()) { // GPU Counter init failed
printf("%s\n", errInfo.c_str());
return -1;
}
return rc;
}
std::string SmartPerfCommand::ExecCommand()
{
LOGI("SmartPerfCommand::ExecCommand start num(%d)", num);
int rc = 0;
int index = 0;
bool callGpuCounterResult = false;
std::vector<SPData> vmap;
const long long freq = 1000;
while (index < num) {
long long lastTime = SPUtils::GetCurTime();
std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> spMap(SPUtils::Cmp);
long long timestamp = SPUtils::GetCurTime();
spMap.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(timestamp)));
for (size_t j = 0; j < configs.size(); j++) {
std::string curParam = configs[j];
SpProfiler *profiler = SpProfilerFactory::GetCmdProfilerItem(COMMAND_MAP.at(curParam), true);
if (profiler != nullptr) {
std::map<std::string, std::string> data = profiler->ItemData();
spMap.insert(data.cbegin(), data.cend());
}
long long lastTime = SPUtils::GetCurTime();
spMap.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(lastTime)));
rc = GetItemInfo(spMap);
if (rc == -1) {
break;
} else if (rc == 1) {
callGpuCounterResult = true;
}
std::cout << std::endl;
int i = 0;
for (auto iter = spMap.cbegin(); iter != spMap.cend(); ++iter) {
printf("order:%d %s=%s\n", i, iter->first.c_str(), iter->second.c_str());
i++;
printf("order:%d %s=%s\n", i++, iter->first.c_str(), iter->second.c_str());
}
std::cout << std::endl;
SPData spdata;
spdata.values.insert(spMap.cbegin(), spMap.cend());
vmap.push_back(spdata);
@ -168,6 +200,18 @@ std::string SmartPerfCommand::ExecCommand()
}
index++;
}
if (callGpuCounterResult) {
int i = 0;
std::map<std::string, std::string> data = GpuCounter::GetInstance().ItemData();
for (auto a = data.begin(); a != data.end(); ++a) {
printf("order:%d %s=%s\n", i++, a->first.c_str(), a->second.c_str());
}
SPData spdata;
spdata.values.insert(data.begin(), data.end());
vmap.push_back(spdata);
}
std::this_thread::sleep_for(std::chrono::milliseconds(freq));
SpCsvUtil::WriteCsv(std::string(outPath.c_str()), vmap);
return std::string("command exec finished!");

View File

@ -162,6 +162,19 @@ SpProfiler *SpProfilerFactory::GetCmdProfilerItem(CommandType commandType, bool
case CommandType::CT_TTRACE:
ProfilerFPS::GetInstance().SetTraceCatch();
break;
default:
break;
}
if (profiler == nullptr) {
profiler = GetCmdProfilerItemContinue(commandType, cmdFlag);
}
return profiler;
}
SpProfiler *SpProfilerFactory::GetCmdProfilerItemContinue(CommandType commandType, bool cmdFlag)
{
SpProfiler *profiler = nullptr;
switch (commandType) {
case CommandType::CT_SNAPSHOT:
if (cmdFlag) {
profiler = &Capture::GetInstance();
@ -172,6 +185,15 @@ SpProfiler *SpProfilerFactory::GetCmdProfilerItem(CommandType commandType, bool
case CommandType::CT_M:
profiler = &MEMORY::GetInstance();
break;
case CommandType::CT_GC:
if (GpuCounter::GetInstance().GetStatus() == GpuCounter::GC_INIT) {
std::map<std::string, std::string> retMap;
GpuCounter::GetInstance().Init("/data/local/tmp/", retMap);
profiler = &GpuCounter::GetInstance();
} else if (GpuCounter::GetInstance().GetStatus() == GpuCounter::GC_START) {
GpuCounter::GetInstance().Check();
}
break;
default:
break;
}

View File

@ -356,6 +356,11 @@ bool SPTask::CheckTcpParam(std::string str, std::string &errorInfo)
keys.insert(a.first.substr(1)); // 不需要前面的'-'
}
auto itr = keys.find("gc"); // editor tcp does not support gc
if (keys.end() != itr) {
keys.erase(itr);
}
return SPUtils::VeriyParameter(keys, str, errorInfo);
}