@@ -66,6 +66,8 @@ void print_usage(const string progname)
66
66
cerr << " -r | --reset | /reset => reset PMU configuration (at your own risk)\n " ;
67
67
cerr << " -csv[=file.csv] | /csv[=file.csv] => output compact CSV format to screen or\n "
68
68
<< " to a file, in case filename is provided\n " ;
69
+ cerr << " -json[=file.json] | /json[=file.json] => output json format to screen or\n "
70
+ << " to a file, in case filename is provided\n " ;
69
71
cerr << " -out filename | /out filename => write all output (stdout and stderr) to specified file\n " ;
70
72
cerr << " event description example: -e core/config=0x30203,name=LD_BLOCKS.STORE_FORWARD/ -e core/fixed,config=0x333/ \n " ;
71
73
cerr << " -e cha/config=0,name=UNC_CHA_CLOCKTICKS/ -e imc/fixed,name=DRAM_CLOCKS/\n " ;
@@ -954,7 +956,9 @@ bool transpose = false;
954
956
bool extendPrintout = false ;
955
957
bool singleHeader = false ;
956
958
std::string separator = " ," ;
959
+ const std::string jsonSeparator = " \" :" ;
957
960
bool sampleSeparator = false ;
961
+ bool outputToJson = false ;
958
962
959
963
struct PrintOffset {
960
964
const std::string entry;
@@ -973,21 +977,41 @@ int getPrintOffsetIdx(const std::string &value) {
973
977
return -1 ;
974
978
}
975
979
976
- void printRowBegin (const std::string & EventName, const CoreCounterState & BeforeState, const CoreCounterState & AfterState, PCM* m)
980
+ void printNewLine (const CsvOutputType outputType) {
981
+ if (outputType == Data)
982
+ cout << " \n " ;
983
+ else if (outputType == Json)
984
+ cout << " }\n " ;
985
+ }
986
+
987
+ void printRowBeginCSV (const std::string & EventName, const CoreCounterState & BeforeState, const CoreCounterState & AfterState, PCM* m)
977
988
{
978
989
printDateForCSV (CsvOutputType::Data, separator);
979
990
cout << EventName << separator << (1000ULL * getInvariantTSC (BeforeState, AfterState)) / m->getNominalFrequency () << separator << getInvariantTSC (BeforeState, AfterState);
980
991
}
981
992
982
-
983
- template <class MetricFunc >
984
- void printRow (const std::string & EventName, MetricFunc metricFunc, const std::vector<CoreCounterState>& BeforeState, const std::vector<CoreCounterState>& AfterState, PCM* m, const CsvOutputType outputType, PrintOffset& printOffset)
993
+ void printRowBeginJson (const std::string & EventName, const CoreCounterState & BeforeState, const CoreCounterState & AfterState, PCM* m)
985
994
{
995
+ cout << " {\" " ;
996
+ printDateForJson (separator, jsonSeparator);
997
+ cout << " Event" << jsonSeparator << " \" " << EventName << " \" " << separator << " ms" << jsonSeparator << (1000ULL * getInvariantTSC (BeforeState, AfterState)) / m->getNominalFrequency ()
998
+ << separator << " InvariantTSC" << jsonSeparator << getInvariantTSC (BeforeState, AfterState);
999
+ }
1000
+
1001
+ void printRowBegin (const std::string & EventName, const CoreCounterState & BeforeState, const CoreCounterState & AfterState, PCM* m, const CsvOutputType outputType, PrintOffset& printOffset) {
986
1002
if (outputType == Data) {
987
- printRowBegin (EventName, BeforeState[ 0 ] , AfterState[ 0 ] , m);
1003
+ printRowBeginCSV (EventName, BeforeState, AfterState, m);
988
1004
for (int i = 0 ; i < printOffset.start ; i++)
989
1005
std::cout << separator;
1006
+ } else if (outputType == Json) {
1007
+ printRowBeginJson (EventName, BeforeState, AfterState, m);
990
1008
}
1009
+ }
1010
+
1011
+ template <class MetricFunc >
1012
+ void printRow (const std::string & EventName, MetricFunc metricFunc, const std::vector<CoreCounterState>& BeforeState, const std::vector<CoreCounterState>& AfterState, PCM* m, const CsvOutputType outputType, PrintOffset& printOffset)
1013
+ {
1014
+ printRowBegin (EventName, BeforeState[0 ], AfterState[0 ], m, outputType, printOffset);
991
1015
992
1016
for (uint32 core = 0 ; core < m->getNumCores (); ++core)
993
1017
{
@@ -1005,13 +1029,15 @@ void printRow(const std::string & EventName, MetricFunc metricFunc, const std::v
1005
1029
cout << separator << " core_SKT" << m->getSocketId (core) << " _CORE" << core;
1006
1030
printOffset.end ++;
1007
1031
}
1008
- else
1032
+ else if (outputType == Json) {
1033
+ cout << separator << " core_SKT" << m->getSocketId (core) << " _CORE" << core <<
1034
+ jsonSeparator << metricFunc (BeforeState[core], AfterState[core]);
1035
+ } else
1009
1036
assert (!" unknown output type" );
1010
1037
}
1011
1038
}
1012
1039
1013
- if (outputType == Data)
1014
- cout << " \n " ;
1040
+ printNewLine (outputType);
1015
1041
};
1016
1042
1017
1043
typedef uint64 (*UncoreMetricFunc)(const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after);
@@ -1089,11 +1115,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1089
1115
{
1090
1116
if (fixedEvents.size ())
1091
1117
{
1092
- if (outputType == Data) {
1093
- printRowBegin (miscName, BeforeState[0 ], AfterState[0 ], m);
1094
- for (int off = 0 ; off < printOffset.start ; off++)
1095
- cout << separator;
1096
- }
1118
+ printRowBegin (miscName, BeforeState[0 ], AfterState[0 ], m, outputType, printOffset);
1097
1119
1098
1120
for (uint32 s = 0 ; s < m->getNumSockets (); ++s)
1099
1121
{
@@ -1111,6 +1133,9 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1111
1133
else if (outputType == Header21) {
1112
1134
cout << separator << type << " _SKT" << s << " _" << miscName << u;
1113
1135
printOffset.end ++;
1136
+ } else if (outputType == Json) {
1137
+ cout << separator << type << " _SKT" << s << " _" << miscName << u
1138
+ << jsonSeparator << fixedMetricFunc (u, BeforeUncoreState[s], AfterUncoreState[s]);
1114
1139
} else
1115
1140
assert (!" unknown output type" );
1116
1141
}
@@ -1119,8 +1144,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1119
1144
if (is_header)
1120
1145
is_header_printed = true ;
1121
1146
1122
- if (outputType == Data)
1123
- cout << " \n " ;
1147
+ printNewLine (outputType);
1124
1148
}
1125
1149
uint32 i = 0 ;
1126
1150
for (auto & event : events)
@@ -1130,11 +1154,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1130
1154
if (is_header && is_header_printed)
1131
1155
break ;
1132
1156
1133
- if (outputType == Data) {
1134
- printRowBegin (name, BeforeState[0 ], AfterState[0 ], m);
1135
- for (int off = 0 ; off < printOffset.start ; off++)
1136
- cout << separator;
1137
- }
1157
+ printRowBegin (name, BeforeState[0 ], AfterState[0 ], m, outputType, printOffset);
1138
1158
1139
1159
for (uint32 s = 0 ; s < m->getNumSockets (); ++s)
1140
1160
{
@@ -1158,6 +1178,11 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1158
1178
cout << separator << type << " _SKT" << s << " _" << miscName << u;
1159
1179
printOffset.end ++;
1160
1180
}
1181
+ else if (outputType == Json)
1182
+ {
1183
+ cout << separator << type << " _SKT" << s << " _" << miscName << u
1184
+ << jsonSeparator << metricFunc (u, i, BeforeUncoreState[s], AfterUncoreState[s]);
1185
+ }
1161
1186
else
1162
1187
{
1163
1188
assert (!" unknown output type" );
@@ -1169,8 +1194,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1169
1194
is_header_printed = true ;
1170
1195
1171
1196
++i;
1172
- if (outputType == Data)
1173
- cout << " \n " ;
1197
+ printNewLine (outputType);
1174
1198
}
1175
1199
};
1176
1200
auto printMSRRows = [&](const MSRScope& scope)
@@ -1184,11 +1208,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1184
1208
if (is_header && is_header_printed)
1185
1209
return false ;
1186
1210
1187
- if (outputType == Data) {
1188
- printRowBegin (name, BeforeState[0 ], AfterState[0 ], m);
1189
- for (int off = 0 ; off < printOffset.start ; off++)
1190
- cout << separator;
1191
- }
1211
+ printRowBegin (name, BeforeState[0 ], AfterState[0 ], m, outputType, printOffset);
1192
1212
1193
1213
switch (scope)
1194
1214
{
@@ -1213,6 +1233,10 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1213
1233
cout << separator << type << " _SKT" << s ;
1214
1234
printOffset.end ++;
1215
1235
}
1236
+ else if (outputType == Json) {
1237
+ cout << separator << type << " _SKT" << s
1238
+ << jsonSeparator << getMSREvent (index, msrType, BeforeSocketState[s], AfterSocketState[s]);
1239
+ }
1216
1240
else
1217
1241
{
1218
1242
assert (!" unknown output type" );
@@ -1240,6 +1264,10 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1240
1264
cout << separator << type << " _SKT" << m->getSocketId (core) << " _CORE" << core;
1241
1265
printOffset.end ++;
1242
1266
}
1267
+ else if (outputType == Json) {
1268
+ cout << separator << type << " _SKT" << m->getSocketId (core) << " _CORE" << core
1269
+ << jsonSeparator << getMSREvent (index, msrType, BeforeState[core], AfterState[core]);
1270
+ }
1243
1271
else
1244
1272
{
1245
1273
assert (!" unknown output type" );
@@ -1251,8 +1279,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1251
1279
if (is_header)
1252
1280
is_header_printed = true ;
1253
1281
1254
- if (outputType == Data)
1255
- cout << " \n " ;
1282
+ printNewLine (outputType);
1256
1283
1257
1284
return true ;
1258
1285
};
@@ -1335,15 +1362,15 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1335
1362
choose (outputType,
1336
1363
[&]() { printUncoreRows (nullptr , (uint32) m->getQPILinksPerSocket (), " LINK" ); },
1337
1364
[&]() { printUncoreRows (nullptr , (uint32) m->getQPILinksPerSocket (), type); },
1338
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getM3UPICounter (u, i, before, after); }, (uint32) m->getQPILinksPerSocket ());
1365
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getM3UPICounter (u, i, before, after); }, (uint32) m->getQPILinksPerSocket (), " LINK " );
1339
1366
});
1340
1367
}
1341
1368
else if (type == " xpi" || type == " upi" || type == " qpi" )
1342
1369
{
1343
1370
choose (outputType,
1344
1371
[&]() { printUncoreRows (nullptr , (uint32) m->getQPILinksPerSocket (), " LINK" ); },
1345
1372
[&]() { printUncoreRows (nullptr , (uint32) m->getQPILinksPerSocket (), type); },
1346
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getXPICounter (u, i, before, after); }, (uint32) m->getQPILinksPerSocket ());
1373
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getXPICounter (u, i, before, after); }, (uint32) m->getQPILinksPerSocket (), " LINK " );
1347
1374
});
1348
1375
}
1349
1376
else if (type == " imc" )
@@ -1360,15 +1387,15 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1360
1387
choose (outputType,
1361
1388
[&]() { printUncoreRows (nullptr , (uint32) m->getMCPerSocket (), " MC" ); },
1362
1389
[&]() { printUncoreRows (nullptr , (uint32) m->getMCPerSocket (), type); },
1363
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getM2MCounter (u, i, before, after); }, (uint32)m->getMCPerSocket ());
1390
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getM2MCounter (u, i, before, after); }, (uint32)m->getMCPerSocket (), " MC " );
1364
1391
});
1365
1392
}
1366
1393
else if (type == " pcu" )
1367
1394
{
1368
1395
choose (outputType,
1369
1396
[&]() { printUncoreRows (nullptr , 1U , " " ); },
1370
1397
[&]() { printUncoreRows (nullptr , 1U , type); },
1371
- [&]() { printUncoreRows ([](const uint32, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getPCUCounter (i, before, after); }, 1U );
1398
+ [&]() { printUncoreRows ([](const uint32, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getPCUCounter (i, before, after); }, 1U , " " );
1372
1399
});
1373
1400
}
1374
1401
else if (type == " ubox" )
@@ -1385,23 +1412,23 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1385
1412
choose (outputType,
1386
1413
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfCBoxes (), " C" ); },
1387
1414
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfCBoxes (), type); },
1388
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getCBOCounter (u, i, before, after); }, (uint32)m->getMaxNumOfCBoxes ());
1415
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getCBOCounter (u, i, before, after); }, (uint32)m->getMaxNumOfCBoxes (), " C " );
1389
1416
});
1390
1417
}
1391
1418
else if (type == " irp" )
1392
1419
{
1393
1420
choose (outputType,
1394
1421
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfIIOStacks (), " IRP" ); },
1395
1422
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfIIOStacks (), type); },
1396
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getIRPCounter (u, i, before, after); }, (uint32)m->getMaxNumOfIIOStacks ());
1423
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getIRPCounter (u, i, before, after); }, (uint32)m->getMaxNumOfIIOStacks (), " IRP " );
1397
1424
});
1398
1425
}
1399
1426
else if (type == " iio" )
1400
1427
{
1401
1428
choose (outputType,
1402
1429
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfIIOStacks (), " IIO" ); },
1403
1430
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfIIOStacks (), type); },
1404
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getIIOCounter (u, i, before, after); }, (uint32)m->getMaxNumOfIIOStacks ());
1431
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getIIOCounter (u, i, before, after); }, (uint32)m->getMaxNumOfIIOStacks (), " IIO " );
1405
1432
});
1406
1433
}
1407
1434
else
@@ -1735,6 +1762,11 @@ void printAll(const PCM::RawPMUConfigs& curPMUConfigs,
1735
1762
std::vector<PCM::RawPMUConfigs>& PMUConfigs,
1736
1763
const bool & isLastGroup)
1737
1764
{
1765
+ if (outputToJson) {
1766
+ printTransposed (curPMUConfigs, m, BeforeState, AfterState, BeforeUncoreState, AfterUncoreState, BeforeSocketState, AfterSocketState, Json, isLastGroup);
1767
+ return ;
1768
+ }
1769
+
1738
1770
static bool displayHeader = true ;
1739
1771
1740
1772
if (!extendPrintout && transpose)
@@ -1843,6 +1875,21 @@ int main(int argc, char* argv[])
1843
1875
}
1844
1876
continue ;
1845
1877
}
1878
+ else if (strncmp (*argv, " -json" , 5 ) == 0 ||
1879
+ strncmp (*argv, " /json" , 5 ) == 0 )
1880
+ {
1881
+ separator = " ,\" " ;
1882
+ outputToJson = true ;
1883
+ string cmd = string (*argv);
1884
+ size_t found = cmd.find (' =' , 5 );
1885
+ if (found != string::npos) {
1886
+ string filename = cmd.substr (found + 1 );
1887
+ if (!filename.empty ()) {
1888
+ m->setOutput (filename);
1889
+ }
1890
+ }
1891
+ continue ;
1892
+ }
1846
1893
else if (mainLoop.parseArg (*argv))
1847
1894
{
1848
1895
continue ;
0 commit comments