Skip to content

Commit f698fc8

Browse files
committed
support pid option in pcm
1 parent 3d45db3 commit f698fc8

File tree

4 files changed

+38
-10
lines changed

4 files changed

+38
-10
lines changed

src/cpucounters.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,7 +2390,7 @@ perf_event_attr PCM_init_perf_event_attr(bool group = true)
23902390
}
23912391
#endif
23922392

2393-
PCM::ErrorCode PCM::program(const PCM::ProgramMode mode_, const void * parameter_, const bool silent)
2393+
PCM::ErrorCode PCM::program(const PCM::ProgramMode mode_, const void * parameter_, const bool silent, const int pid)
23942394
{
23952395
#ifdef __linux__
23962396
if (isNMIWatchdogEnabled(silent))
@@ -2689,6 +2689,11 @@ PCM::ErrorCode PCM::program(const PCM::ProgramMode mode_, const void * parameter
26892689
<< core_fixed_counter_num_max << " available\n";
26902690
return PCM::UnknownError;
26912691
}
2692+
if (pid != -1 && canUsePerf == false)
2693+
{
2694+
std::cerr << "PCM ERROR: pid monitoring is only supported with Linux perf_event driver\n";
2695+
return PCM::UnknownError;
2696+
}
26922697

26932698
programmed_pmu = true;
26942699

@@ -2703,11 +2708,11 @@ PCM::ErrorCode PCM::program(const PCM::ProgramMode mode_, const void * parameter
27032708
{
27042709
if (isCoreOnline(i) == false) continue;
27052710

2706-
std::packaged_task<void()> task([this, i, mode_, pExtDesc, &programmingStatuses]() -> void
2711+
std::packaged_task<void()> task([this, i, mode_, pExtDesc, &programmingStatuses, &pid]() -> void
27072712
{
27082713
TemporalThreadAffinity tempThreadAffinity(i, false); // speedup trick for Linux
27092714

2710-
programmingStatuses[i] = programCoreCounters(i, mode_, pExtDesc, lastProgrammedCustomCounters[i]);
2715+
programmingStatuses[i] = programCoreCounters(i, mode_, pExtDesc, lastProgrammedCustomCounters[i], pid);
27112716
});
27122717
asyncCoreResults.push_back(task.get_future());
27132718
coreTaskQueues[i]->push(task);
@@ -2807,8 +2812,10 @@ std::mutex printErrorMutex;
28072812
PCM::ErrorCode PCM::programCoreCounters(const int i /* core */,
28082813
const PCM::ProgramMode mode_,
28092814
const ExtendedCustomCoreEventDescription * pExtDesc,
2810-
std::vector<EventSelectRegister> & result)
2815+
std::vector<EventSelectRegister> & result,
2816+
const int pid)
28112817
{
2818+
(void) pid; // to silence uused param warning on non Linux OS
28122819
// program core counters
28132820

28142821
result.clear();
@@ -2840,10 +2847,10 @@ PCM::ErrorCode PCM::programCoreCounters(const int i /* core */,
28402847
};
28412848
#ifdef PCM_USE_PERF
28422849
int leader_counter = -1;
2843-
auto programPerfEvent = [this, &leader_counter, &i](perf_event_attr & e, const int eventPos, const std::string & eventName) -> bool
2850+
auto programPerfEvent = [this, &leader_counter, &i, &pid](perf_event_attr & e, const int eventPos, const std::string & eventName) -> bool
28442851
{
28452852
// if (i == 0) std::cerr << "DEBUG: programming event "<< std::hex << e.config << std::dec << "\n";
2846-
if ((perfEventHandle[i][eventPos] = syscall(SYS_perf_event_open, &e, -1,
2853+
if ((perfEventHandle[i][eventPos] = syscall(SYS_perf_event_open, &e, pid,
28472854
i /* core id */, leader_counter /* group leader */, 0)) <= 0)
28482855
{
28492856
std::lock_guard<std::mutex> _(printErrorMutex);

src/cpucounters.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ class PCM_API PCM
894894
std::vector<std::vector<EventSelectRegister> > lastProgrammedCustomCounters;
895895
uint32 checkCustomCoreProgramming(std::shared_ptr<SafeMsrHandle> msr);
896896
ErrorCode programCoreCounters(int core, const PCM::ProgramMode mode, const ExtendedCustomCoreEventDescription * pExtDesc,
897-
std::vector<EventSelectRegister> & programmedCustomCounters);
897+
std::vector<EventSelectRegister> & programmedCustomCounters, const int pid);
898898

899899
bool PMUinUse();
900900
void cleanupPMU(const bool silent = false);
@@ -1110,6 +1110,8 @@ class PCM_API PCM
11101110
/*! \brief Programs performance counters
11111111
\param mode_ mode of programming, see ProgramMode definition
11121112
\param parameter_ optional parameter for some of programming modes
1113+
\param silent set to true to silence diagnostic messages
1114+
\param pid restrict core metrics only to specified pid (process id)
11131115
11141116
Call this method before you start using the performance counting routines.
11151117
@@ -1118,7 +1120,7 @@ class PCM_API PCM
11181120
program PMUs: Intel(r) VTune(tm), Intel(r) Performance Tuning Utility (PTU). This code may make
11191121
VTune or PTU measurements invalid. VTune or PTU measurement may make measurement with this code invalid. Please enable either usage of these routines or VTune/PTU/etc.
11201122
*/
1121-
ErrorCode program(const ProgramMode mode_ = DEFAULT_EVENTS, const void * parameter_ = NULL, const bool silent = false); // program counters and start counting
1123+
ErrorCode program(const ProgramMode mode_ = DEFAULT_EVENTS, const void * parameter_ = NULL, const bool silent = false, const int pid = -1); // program counters and start counting
11221124

11231125
/*! \brief checks the error and suggests solution and/or exits the process
11241126
\param code error code from the 'program' call

src/pcm.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ void print_help(const string prog_name)
8888
cerr << " will read counters only after external program finishes\n";
8989
cerr << " Supported <options> are: \n";
9090
cerr << " -h | --help | /h => print this help and exit\n";
91+
cerr << " -pid PID | /pid PID => collect core metrics only for specified process ID\n";
9192
#ifdef _MSC_VER
9293
cerr << " --uninstallDriver | --installDriver=> (un)install driver\n";
9394
#endif
@@ -1155,7 +1156,7 @@ int main(int argc, char * argv[])
11551156
// if delay is not specified: use either default (1 second),
11561157
// or only read counters before or after PCM started: keep PCM blocked
11571158
double delay = -1.0;
1158-
1159+
int pid{-1};
11591160
char *sysCmd = NULL;
11601161
char **sysArgv = NULL;
11611162
bool show_core_output = true;
@@ -1166,6 +1167,8 @@ int main(int argc, char * argv[])
11661167
bool reset_pmu = false;
11671168
bool disable_JKT_workaround = false; // as per http://software.intel.com/en-us/articles/performance-impact-when-sampling-certain-llc-events-on-snb-ep-with-vtune
11681169

1170+
parseParam(argc, argv, "pid", [&pid](const char* p) { if (p) pid = atoi(p); });
1171+
11691172
MainLoop mainLoop;
11701173
std::bitset<MAX_CORES> ycores;
11711174
string program = string(argv[0]);
@@ -1259,6 +1262,12 @@ int main(int argc, char * argv[])
12591262
}
12601263
continue;
12611264
}
1265+
else if (strncmp(*argv, "-pid", 4) == 0 || strncmp(*argv, "/pid", 4) == 0)
1266+
{
1267+
argv++;
1268+
argc--;
1269+
continue;
1270+
}
12621271
else
12631272
if (mainLoop.parseArg(*argv))
12641273
{
@@ -1342,7 +1351,7 @@ int main(int argc, char * argv[])
13421351
}
13431352

13441353
// program() creates common semaphore for the singleton, so ideally to be called before any other references to PCM
1345-
PCM::ErrorCode status = m->program();
1354+
const PCM::ErrorCode status = m->program(PCM::DEFAULT_EVENTS, nullptr, false, pid);
13461355

13471356
switch (status)
13481357
{
@@ -1367,6 +1376,11 @@ int main(int argc, char * argv[])
13671376
SystemCounterState sstate1, sstate2;
13681377
const auto cpu_model = m->getCPUModel();
13691378

1379+
if (pid != -1)
1380+
{
1381+
cerr << "Collecting core metrics for process ID " << pid << "\n";
1382+
}
1383+
13701384
if ((sysCmd != NULL) && (delay <= 0.0)) {
13711385
// in case external command is provided in command line, and
13721386
// delay either not provided (-1) or is zero

src/utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@ void parseParam(int argc, char* argv[], const char* param, F f)
307307
{
308308
argv++;
309309
argc--;
310+
if (argc == 0)
311+
{
312+
std::cerr << "ERROR: no parameter provided for option " << param << "\n";
313+
exit(EXIT_FAILURE);
314+
}
310315
f(*argv);
311316
continue;
312317
}

0 commit comments

Comments
 (0)