@@ -56,6 +56,8 @@ void print_usage(const string progname)
56
56
cerr << " -r | --reset | /reset => reset PMU configuration (at your own risk)\n " ;
57
57
cerr << " -csv[=file.csv] | /csv[=file.csv] => output compact CSV format to screen or\n "
58
58
<< " to a file, in case filename is provided\n " ;
59
+ cerr << " -json[=file.json] | /json[=file.json] => output json format to screen or\n "
60
+ << " to a file, in case filename is provided\n " ;
59
61
cerr << " -out filename | /out filename => write all output (stdout and stderr) to specified file\n " ;
60
62
cerr << " event description example: -e core/config=0x30203,name=LD_BLOCKS.STORE_FORWARD/ -e core/fixed,config=0x333/ \n " ;
61
63
cerr << " -e cha/config=0,name=UNC_CHA_CLOCKTICKS/ -e imc/fixed,name=DRAM_CLOCKS/\n " ;
@@ -944,7 +946,9 @@ bool transpose = false;
944
946
bool extendPrintout = false ;
945
947
bool singleHeader = false ;
946
948
std::string separator = " ," ;
949
+ const std::string jsonSeparator = " \" :" ;
947
950
bool sampleSeparator = false ;
951
+ bool outputToJson = false ;
948
952
949
953
struct PrintOffset {
950
954
const std::string entry;
@@ -963,21 +967,41 @@ int getPrintOffsetIdx(const std::string &value) {
963
967
return -1 ;
964
968
}
965
969
966
- void printRowBegin (const std::string & EventName, const CoreCounterState & BeforeState, const CoreCounterState & AfterState, PCM* m)
970
+ void printNewLine (const CsvOutputType outputType) {
971
+ if (outputType == Data)
972
+ cout << " \n " ;
973
+ else if (outputType == Json)
974
+ cout << " }\n " ;
975
+ }
976
+
977
+ void printRowBeginCSV (const std::string & EventName, const CoreCounterState & BeforeState, const CoreCounterState & AfterState, PCM* m)
967
978
{
968
979
printDateForCSV (CsvOutputType::Data, separator);
969
980
cout << EventName << separator << (1000ULL * getInvariantTSC (BeforeState, AfterState)) / m->getNominalFrequency () << separator << getInvariantTSC (BeforeState, AfterState);
970
981
}
971
982
972
-
973
- template <class MetricFunc >
974
- 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)
983
+ void printRowBeginJson (const std::string & EventName, const CoreCounterState & BeforeState, const CoreCounterState & AfterState, PCM* m)
975
984
{
985
+ cout << " {\" " ;
986
+ printDateForJson (separator, jsonSeparator);
987
+ cout << " Event" << jsonSeparator << " \" " << EventName << " \" " << separator << " ms" << jsonSeparator << (1000ULL * getInvariantTSC (BeforeState, AfterState)) / m->getNominalFrequency ()
988
+ << separator << " InvariantTSC" << jsonSeparator << getInvariantTSC (BeforeState, AfterState);
989
+ }
990
+
991
+ void printRowBegin (const std::string & EventName, const CoreCounterState & BeforeState, const CoreCounterState & AfterState, PCM* m, const CsvOutputType outputType, PrintOffset& printOffset) {
976
992
if (outputType == Data) {
977
- printRowBegin (EventName, BeforeState[ 0 ] , AfterState[ 0 ] , m);
993
+ printRowBeginCSV (EventName, BeforeState, AfterState, m);
978
994
for (int i = 0 ; i < printOffset.start ; i++)
979
995
std::cout << separator;
996
+ } else if (outputType == Json) {
997
+ printRowBeginJson (EventName, BeforeState, AfterState, m);
980
998
}
999
+ }
1000
+
1001
+ template <class MetricFunc >
1002
+ 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)
1003
+ {
1004
+ printRowBegin (EventName, BeforeState[0 ], AfterState[0 ], m, outputType, printOffset);
981
1005
982
1006
for (uint32 core = 0 ; core < m->getNumCores (); ++core)
983
1007
{
@@ -995,13 +1019,15 @@ void printRow(const std::string & EventName, MetricFunc metricFunc, const std::v
995
1019
cout << separator << " core_SKT" << m->getSocketId (core) << " _CORE" << core;
996
1020
printOffset.end ++;
997
1021
}
998
- else
1022
+ else if (outputType == Json) {
1023
+ cout << separator << " core_SKT" << m->getSocketId (core) << " _CORE" << core <<
1024
+ jsonSeparator << metricFunc (BeforeState[core], AfterState[core]);
1025
+ } else
999
1026
assert (!" unknown output type" );
1000
1027
}
1001
1028
}
1002
1029
1003
- if (outputType == Data)
1004
- cout << " \n " ;
1030
+ printNewLine (outputType);
1005
1031
};
1006
1032
1007
1033
typedef uint64 (*UncoreMetricFunc)(const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after);
@@ -1079,11 +1105,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1079
1105
{
1080
1106
if (fixedEvents.size ())
1081
1107
{
1082
- if (outputType == Data) {
1083
- printRowBegin (miscName, BeforeState[0 ], AfterState[0 ], m);
1084
- for (int off = 0 ; off < printOffset.start ; off++)
1085
- cout << separator;
1086
- }
1108
+ printRowBegin (miscName, BeforeState[0 ], AfterState[0 ], m, outputType, printOffset);
1087
1109
1088
1110
for (uint32 s = 0 ; s < m->getNumSockets (); ++s)
1089
1111
{
@@ -1101,6 +1123,9 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1101
1123
else if (outputType == Header21) {
1102
1124
cout << separator << type << " _SKT" << s << " _" << miscName << u;
1103
1125
printOffset.end ++;
1126
+ } else if (outputType == Json) {
1127
+ cout << separator << type << " _SKT" << s << " _" << miscName << u
1128
+ << jsonSeparator << fixedMetricFunc (u, BeforeUncoreState[s], AfterUncoreState[s]);
1104
1129
} else
1105
1130
assert (!" unknown output type" );
1106
1131
}
@@ -1109,8 +1134,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1109
1134
if (is_header)
1110
1135
is_header_printed = true ;
1111
1136
1112
- if (outputType == Data)
1113
- cout << " \n " ;
1137
+ printNewLine (outputType);
1114
1138
}
1115
1139
uint32 i = 0 ;
1116
1140
for (auto & event : events)
@@ -1120,11 +1144,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1120
1144
if (is_header && is_header_printed)
1121
1145
break ;
1122
1146
1123
- if (outputType == Data) {
1124
- printRowBegin (name, BeforeState[0 ], AfterState[0 ], m);
1125
- for (int off = 0 ; off < printOffset.start ; off++)
1126
- cout << separator;
1127
- }
1147
+ printRowBegin (name, BeforeState[0 ], AfterState[0 ], m, outputType, printOffset);
1128
1148
1129
1149
for (uint32 s = 0 ; s < m->getNumSockets (); ++s)
1130
1150
{
@@ -1148,6 +1168,11 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1148
1168
cout << separator << type << " _SKT" << s << " _" << miscName << u;
1149
1169
printOffset.end ++;
1150
1170
}
1171
+ else if (outputType == Json)
1172
+ {
1173
+ cout << separator << type << " _SKT" << s << " _" << miscName << u
1174
+ << jsonSeparator << metricFunc (u, i, BeforeUncoreState[s], AfterUncoreState[s]);
1175
+ }
1151
1176
else
1152
1177
{
1153
1178
assert (!" unknown output type" );
@@ -1159,8 +1184,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1159
1184
is_header_printed = true ;
1160
1185
1161
1186
++i;
1162
- if (outputType == Data)
1163
- cout << " \n " ;
1187
+ printNewLine (outputType);
1164
1188
}
1165
1189
};
1166
1190
auto printMSRRows = [&](const MSRScope& scope)
@@ -1174,11 +1198,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1174
1198
if (is_header && is_header_printed)
1175
1199
return false ;
1176
1200
1177
- if (outputType == Data) {
1178
- printRowBegin (name, BeforeState[0 ], AfterState[0 ], m);
1179
- for (int off = 0 ; off < printOffset.start ; off++)
1180
- cout << separator;
1181
- }
1201
+ printRowBegin (name, BeforeState[0 ], AfterState[0 ], m, outputType, printOffset);
1182
1202
1183
1203
switch (scope)
1184
1204
{
@@ -1203,6 +1223,10 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1203
1223
cout << separator << type << " _SKT" << s ;
1204
1224
printOffset.end ++;
1205
1225
}
1226
+ else if (outputType == Json) {
1227
+ cout << separator << type << " _SKT" << s
1228
+ << jsonSeparator << getMSREvent (index, msrType, BeforeSocketState[s], AfterSocketState[s]);
1229
+ }
1206
1230
else
1207
1231
{
1208
1232
assert (!" unknown output type" );
@@ -1230,6 +1254,10 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1230
1254
cout << separator << type << " _SKT" << m->getSocketId (core) << " _CORE" << core;
1231
1255
printOffset.end ++;
1232
1256
}
1257
+ else if (outputType == Json) {
1258
+ cout << separator << type << " _SKT" << m->getSocketId (core) << " _CORE" << core
1259
+ << jsonSeparator << getMSREvent (index, msrType, BeforeState[core], AfterState[core]);
1260
+ }
1233
1261
else
1234
1262
{
1235
1263
assert (!" unknown output type" );
@@ -1241,8 +1269,7 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1241
1269
if (is_header)
1242
1270
is_header_printed = true ;
1243
1271
1244
- if (outputType == Data)
1245
- cout << " \n " ;
1272
+ printNewLine (outputType);
1246
1273
1247
1274
return true ;
1248
1275
};
@@ -1325,15 +1352,15 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1325
1352
choose (outputType,
1326
1353
[&]() { printUncoreRows (nullptr , (uint32) m->getQPILinksPerSocket (), " LINK" ); },
1327
1354
[&]() { printUncoreRows (nullptr , (uint32) m->getQPILinksPerSocket (), type); },
1328
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getM3UPICounter (u, i, before, after); }, (uint32) m->getQPILinksPerSocket ());
1355
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getM3UPICounter (u, i, before, after); }, (uint32) m->getQPILinksPerSocket (), " LINK " );
1329
1356
});
1330
1357
}
1331
1358
else if (type == " xpi" || type == " upi" || type == " qpi" )
1332
1359
{
1333
1360
choose (outputType,
1334
1361
[&]() { printUncoreRows (nullptr , (uint32) m->getQPILinksPerSocket (), " LINK" ); },
1335
1362
[&]() { printUncoreRows (nullptr , (uint32) m->getQPILinksPerSocket (), type); },
1336
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getXPICounter (u, i, before, after); }, (uint32) m->getQPILinksPerSocket ());
1363
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getXPICounter (u, i, before, after); }, (uint32) m->getQPILinksPerSocket (), " LINK " );
1337
1364
});
1338
1365
}
1339
1366
else if (type == " imc" )
@@ -1350,15 +1377,15 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1350
1377
choose (outputType,
1351
1378
[&]() { printUncoreRows (nullptr , (uint32) m->getMCPerSocket (), " MC" ); },
1352
1379
[&]() { printUncoreRows (nullptr , (uint32) m->getMCPerSocket (), type); },
1353
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getM2MCounter (u, i, before, after); }, (uint32)m->getMCPerSocket ());
1380
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getM2MCounter (u, i, before, after); }, (uint32)m->getMCPerSocket (), " MC " );
1354
1381
});
1355
1382
}
1356
1383
else if (type == " pcu" )
1357
1384
{
1358
1385
choose (outputType,
1359
1386
[&]() { printUncoreRows (nullptr , 1U , " " ); },
1360
1387
[&]() { printUncoreRows (nullptr , 1U , type); },
1361
- [&]() { printUncoreRows ([](const uint32, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getPCUCounter (i, before, after); }, 1U );
1388
+ [&]() { printUncoreRows ([](const uint32, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getPCUCounter (i, before, after); }, 1U , " " );
1362
1389
});
1363
1390
}
1364
1391
else if (type == " ubox" )
@@ -1375,23 +1402,23 @@ void printTransposed(const PCM::RawPMUConfigs& curPMUConfigs,
1375
1402
choose (outputType,
1376
1403
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfCBoxes (), " C" ); },
1377
1404
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfCBoxes (), type); },
1378
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getCBOCounter (u, i, before, after); }, (uint32)m->getMaxNumOfCBoxes ());
1405
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getCBOCounter (u, i, before, after); }, (uint32)m->getMaxNumOfCBoxes (), " C " );
1379
1406
});
1380
1407
}
1381
1408
else if (type == " irp" )
1382
1409
{
1383
1410
choose (outputType,
1384
1411
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfIIOStacks (), " IRP" ); },
1385
1412
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfIIOStacks (), type); },
1386
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getIRPCounter (u, i, before, after); }, (uint32)m->getMaxNumOfIIOStacks ());
1413
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getIRPCounter (u, i, before, after); }, (uint32)m->getMaxNumOfIIOStacks (), " IRP " );
1387
1414
});
1388
1415
}
1389
1416
else if (type == " iio" )
1390
1417
{
1391
1418
choose (outputType,
1392
1419
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfIIOStacks (), " IIO" ); },
1393
1420
[&]() { printUncoreRows (nullptr , (uint32) m->getMaxNumOfIIOStacks (), type); },
1394
- [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getIIOCounter (u, i, before, after); }, (uint32)m->getMaxNumOfIIOStacks ());
1421
+ [&]() { printUncoreRows ([](const uint32 u, const uint32 i, const ServerUncoreCounterState& before, const ServerUncoreCounterState& after) { return getIIOCounter (u, i, before, after); }, (uint32)m->getMaxNumOfIIOStacks (), " IIO " );
1395
1422
});
1396
1423
}
1397
1424
else
@@ -1725,6 +1752,11 @@ void printAll(const PCM::RawPMUConfigs& curPMUConfigs,
1725
1752
std::vector<PCM::RawPMUConfigs>& PMUConfigs,
1726
1753
const bool & isLastGroup)
1727
1754
{
1755
+ if (outputToJson) {
1756
+ printTransposed (curPMUConfigs, m, BeforeState, AfterState, BeforeUncoreState, AfterUncoreState, BeforeSocketState, AfterSocketState, Json, isLastGroup);
1757
+ return ;
1758
+ }
1759
+
1728
1760
static bool displayHeader = true ;
1729
1761
1730
1762
if (!extendPrintout && transpose)
@@ -1833,6 +1865,21 @@ int main(int argc, char* argv[])
1833
1865
}
1834
1866
continue ;
1835
1867
}
1868
+ else if (strncmp (*argv, " -json" , 5 ) == 0 ||
1869
+ strncmp (*argv, " /json" , 5 ) == 0 )
1870
+ {
1871
+ separator = " ,\" " ;
1872
+ outputToJson = true ;
1873
+ string cmd = string (*argv);
1874
+ size_t found = cmd.find (' =' , 5 );
1875
+ if (found != string::npos) {
1876
+ string filename = cmd.substr (found + 1 );
1877
+ if (!filename.empty ()) {
1878
+ m->setOutput (filename);
1879
+ }
1880
+ }
1881
+ continue ;
1882
+ }
1836
1883
else if (mainLoop.parseArg (*argv))
1837
1884
{
1838
1885
continue ;
0 commit comments