@@ -341,8 +341,8 @@ void print_usage(const string & progname)
341
341
cout << " -silent => silence information output and print only measurements\n " ;
342
342
cout << " --version => print application version\n " ;
343
343
cout << " -i[=number] | /i[=number] => allow to determine number of iterations\n " ;
344
- // cout << " -csv[=file.csv] | /csv[=file.csv] => output compact CSV format to screen or\n"
345
- // << " to a file, in case filename is provided\n";
344
+ cout << " -csv[=file.csv] | /csv[=file.csv] => output compact CSV format to screen or\n "
345
+ << " to a file, in case filename is provided\n " ;
346
346
cout << " [-m imc_profile] [-p pcu_profile] [-a freq_band0] [-b freq_band1] [-c freq_band2]\n\n " ;
347
347
cout << " Where: imc_profile, pcu_profile, freq_band0, freq_band1 and freq_band2 are the following:\n " ;
348
348
cout << " <imc_profile> - profile (counter group) for IMC PMU. Possible values are: 0,1,2,3,4,-1 \n " ;
@@ -382,8 +382,64 @@ struct Metric
382
382
Metric () = default ;
383
383
};
384
384
385
- void printMetrics (const std::string & header, const std::vector<Metric> & metrics, const bool skipZeroValues = false )
385
+ bool csv = false ;
386
+ bool csv_header = false ;
387
+
388
+ void printMetrics (const std::string & header, const std::vector<Metric> & metrics, const CsvOutputType outputType, const bool skipZeroValues = false )
386
389
{
390
+ if (csv)
391
+ {
392
+ const auto numMetrics = metrics.size ();
393
+ choose (outputType,
394
+ [&]() {
395
+ for (size_t i = 0 ; i < numMetrics; ++i)
396
+ {
397
+ cout << header << ' ,' ;
398
+ }
399
+ },
400
+ [&]() {
401
+ for (size_t i = 0 ; i < numMetrics; ++i)
402
+ {
403
+ cout << metrics[i].name ;
404
+ if (!metrics[i].unit .empty ())
405
+ {
406
+ cout << ' (' << metrics[i].unit << ' )' ;
407
+ }
408
+ cout << ' ,' ;
409
+ }
410
+ },
411
+ [&]() {
412
+ for (size_t i = 0 ; i < numMetrics; ++i)
413
+ {
414
+ if (std::holds_alternative<uint64>(metrics[i].value ))
415
+ {
416
+ cout << std::get<uint64>(metrics[i].value );
417
+ }
418
+ else if (std::holds_alternative<double >(metrics[i].value ))
419
+ {
420
+ cout << std::get<double >(metrics[i].value );
421
+ }
422
+ else if (std::holds_alternative<int64>(metrics[i].value ))
423
+ {
424
+ cout << std::get<int64>(metrics[i].value );
425
+ }
426
+ else if (std::holds_alternative<int32>(metrics[i].value ))
427
+ {
428
+ cout << std::get<int32>(metrics[i].value );
429
+ }
430
+ else if (std::holds_alternative<bool >(metrics[i].value ))
431
+ {
432
+ cout << (std::get<bool >(metrics[i].value ) ? ' 1' : ' 0' );
433
+ }
434
+ else
435
+ {
436
+ assert (false && " Unknown metric type" );
437
+ }
438
+ cout << ' ,' ;
439
+ }
440
+ });
441
+ return ;
442
+ }
387
443
cout << header << " ; " ;
388
444
for (const auto & metric : metrics)
389
445
{
@@ -444,14 +500,14 @@ void printMetrics(const std::string & header, const std::vector<Metric> & metric
444
500
cout << " \n " ;
445
501
}
446
502
447
- void printMetrics (const std::string & header, const std::initializer_list<Metric> & metrics, const bool skipZeroValues = false )
503
+ void printMetrics (const std::string & header, const std::initializer_list<Metric> & metrics, const CsvOutputType outputType, const bool skipZeroValues = false )
448
504
{
449
505
std::vector<Metric> metricsVec;
450
506
for (const auto & metric : metrics)
451
507
{
452
508
metricsVec.push_back (metric);
453
509
}
454
- printMetrics (header, metricsVec, skipZeroValues);
510
+ printMetrics (header, metricsVec, outputType, skipZeroValues);
455
511
}
456
512
457
513
PCM_MAIN_NOTHROW;
@@ -479,7 +535,6 @@ int mainThrows(int argc, char * argv[])
479
535
freq_band[1 ] = default_freq_band[1 ];
480
536
freq_band[2 ] = default_freq_band[2 ];
481
537
482
- bool csv = false ;
483
538
MainLoop mainLoop;
484
539
string program = string (argv[0 ]);
485
540
@@ -504,10 +559,12 @@ int mainThrows(int argc, char * argv[])
504
559
else if (check_argument_equals (*argv, {" -csv" , " /csv" }))
505
560
{
506
561
csv = true ;
562
+ csv_header = true ;
507
563
}
508
564
else if (extract_argument_value (*argv, {" -csv" , " /csv" }, arg_value))
509
565
{
510
566
csv = true ;
567
+ csv_header = true ;
511
568
if (!arg_value.empty ()) {
512
569
m->setOutput (arg_value);
513
570
}
@@ -684,10 +741,17 @@ int mainThrows(int argc, char * argv[])
684
741
685
742
if (PERF_LIMIT_REASON_TPMI_Supported) PERF_LIMIT_REASON_TPMI::reset (max_pm_modules);
686
743
687
- auto printAll = [&](const int delay_ms)
744
+ auto printAll = [&](const int delay_ms, const CsvOutputType outputType )
688
745
{
689
- cout << " Time elapsed: " << AfterTime - BeforeTime << " ms\n " ;
690
- cout << " Called sleep function for " << delay_ms << " ms\n " ;
746
+ if (csv)
747
+ {
748
+ printDateForCSV (outputType);
749
+ }
750
+ else
751
+ {
752
+ cout << " Time elapsed: " << AfterTime - BeforeTime << " ms\n " ;
753
+ cout << " Called sleep function for " << delay_ms << " ms\n " ;
754
+ }
691
755
for (uint32 socket = 0 ; socket < numSockets; ++socket)
692
756
{
693
757
if (nCorePowerLicenses)
@@ -699,7 +763,7 @@ int mainThrows(int argc, char * argv[])
699
763
{
700
764
metrics.push_back (Metric (" Core Power License " + std::to_string (l), getPowerLicenseResidency (l, beforeSocketState[socket], afterSocketState[socket]), " %" ));
701
765
}
702
- printMetrics (" S" + std::to_string (socket), metrics);
766
+ printMetrics (" S" + std::to_string (socket), metrics, outputType );
703
767
}
704
768
for (uint32 port = 0 ; port < m->getQPILinksPerSocket (); ++port)
705
769
{
@@ -708,7 +772,7 @@ int mainThrows(int argc, char * argv[])
708
772
Metric (std::string (m->xPI ()) + " Clocks" , getQPIClocks (port, BeforeState[socket], AfterState[socket]), " " ),
709
773
Metric (" L0p Tx Cycles" , 100 . * getNormalizedQPIL0pTxCycles (port, BeforeState[socket], AfterState[socket]), " %" ),
710
774
Metric (" L1 Cycles" , 100 . * getNormalizedQPIL1Cycles (port, BeforeState[socket], AfterState[socket]), " %" )
711
- });
775
+ }, outputType );
712
776
}
713
777
for (uint32 channel = 0 ; channel < m->getMCChannelsPerSocket (); ++channel)
714
778
{
@@ -723,7 +787,7 @@ int mainThrows(int argc, char * argv[])
723
787
getCKEOffAverageCycles (channel, getFirstRank (imc_profile), BeforeState[socket], AfterState[socket]), " " ),
724
788
Metric (" Rank" + std::to_string (getFirstRank (imc_profile)) + " Cycles per transition" ,
725
789
getCyclesPerTransition (channel, getFirstRank (imc_profile), BeforeState[socket], AfterState[socket]), " " )
726
- });
790
+ }, outputType );
727
791
728
792
printMetrics (" S" + std::to_string (socket) + " CH" + std::to_string (channel),
729
793
{
@@ -734,7 +798,7 @@ int mainThrows(int argc, char * argv[])
734
798
getCKEOffAverageCycles (channel, getSecondRank (imc_profile), BeforeState[socket], AfterState[socket]), " " ),
735
799
Metric (" Rank" + std::to_string (getSecondRank (imc_profile)) + " Cycles per transition" ,
736
800
getCyclesPerTransition (channel, getSecondRank (imc_profile), BeforeState[socket], AfterState[socket]), " " )
737
- });
801
+ }, outputType );
738
802
} else if (imc_profile == 4 )
739
803
{
740
804
printMetrics (" S" + std::to_string (socket) + " CH" + std::to_string (channel),
@@ -743,55 +807,51 @@ int mainThrows(int argc, char * argv[])
743
807
Metric (" Self-refresh cycles" , getSelfRefreshCycles (channel, BeforeState[socket], AfterState[socket]), " " ),
744
808
Metric (" Self-refresh transitions" , getSelfRefreshTransitions (channel, BeforeState[socket], AfterState[socket]), " " ),
745
809
Metric (" PPD cycles" , getPPDCycles (channel, BeforeState[socket], AfterState[socket]), " " )
746
- });
810
+ }, outputType );
747
811
}
748
812
}
749
813
750
814
for (uint32 u = 0 ; u < m->getMaxNumOfUncorePMUs (PCM::PCU_PMU_ID); ++u)
751
815
{
752
- auto getHeader = [&socket,&m,&u, &BeforeState, &AfterState] ()
816
+ std::string header = " S" + std::to_string (socket);
817
+ if (m->getMaxNumOfUncorePMUs (PCM::PCU_PMU_ID) > 1 )
753
818
{
754
- std::string header = " S" + std::to_string (socket);
755
- if (m->getMaxNumOfUncorePMUs (PCM::PCU_PMU_ID) > 1 )
756
- {
757
- header += " U" + std::to_string (u);
758
- }
759
- return header;
760
- };
819
+ header += " U" + std::to_string (u);
820
+ }
761
821
std::vector<Metric> metrics;
762
822
switch (pcu_profile)
763
823
{
764
824
case 0 :
765
825
if (cpu_family_model == PCM::HASWELLX || cpu_family_model == PCM::BDX_DE || cpu_family_model == PCM::SKX)
766
826
break ;
767
827
768
- printMetrics (getHeader () ,
828
+ printMetrics (header ,
769
829
{
770
830
Metric (" PCUClocks" , getPCUClocks (u, BeforeState[socket], AfterState[socket]), " " ),
771
831
Metric (" Freq band 0 cycles" , 100 . * getNormalizedPCUCounter (u, 1 , BeforeState[socket], AfterState[socket]), " %" ),
772
832
Metric (" Freq band 1 cycles" , 100 . * getNormalizedPCUCounter (u, 2 , BeforeState[socket], AfterState[socket]), " %" ),
773
833
Metric (" Freq band 2 cycles" , 100 . * getNormalizedPCUCounter (u, 3 , BeforeState[socket], AfterState[socket]), " %" )
774
- });
834
+ }, outputType );
775
835
break ;
776
836
777
837
case 1 :
778
- printMetrics (getHeader () ,
838
+ printMetrics (header ,
779
839
{
780
840
Metric (" PCUClocks" , getPCUClocks (u, BeforeState[socket], AfterState[socket]), " " ),
781
841
Metric (cpu_family_model == PCM::SKX ? " C0_1-state residency" : " C0-state residency" , getNormalizedPCUCounter (u, 1 , BeforeState[socket], AfterState[socket]), " " ),
782
842
Metric (" C3-state residency" , getNormalizedPCUCounter (u, 2 , BeforeState[socket], AfterState[socket]), " " ),
783
843
Metric (cpu_family_model == PCM::SKX ? " C6_7-state residency" : " C6-state residency" , getNormalizedPCUCounter (u, 3 , BeforeState[socket], AfterState[socket]), " " )
784
- });
844
+ }, outputType );
785
845
break ;
786
846
787
847
case 2 :
788
- printMetrics (getHeader () ,
848
+ printMetrics (header ,
789
849
{
790
850
Metric (" PCUClocks" , getPCUClocks (u, BeforeState[socket], AfterState[socket]), " " ),
791
851
Metric (" Internal prochot cycles" , 100 . * getNormalizedPCUCounter (u, 1 , BeforeState[socket], AfterState[socket]), " %" ),
792
852
Metric (" External prochot cycles" , 100 . * getNormalizedPCUCounter (u, 2 , BeforeState[socket], AfterState[socket]), " %" ),
793
853
Metric (" Thermal freq limit cycles" , 100 . * getNormalizedPCUCounter (u, 3 , BeforeState[socket], AfterState[socket]), " %" )
794
- });
854
+ }, outputType );
795
855
break ;
796
856
797
857
case 3 :
@@ -809,7 +869,7 @@ int mainThrows(int argc, char * argv[])
809
869
{
810
870
metrics.push_back (Metric (" Clipped freq limit cycles" , 100 . * getNormalizedPCUCounter (u, 3 , BeforeState[socket], AfterState[socket]), " %" ));
811
871
}
812
- printMetrics (getHeader () , metrics);
872
+ printMetrics (header , metrics, outputType );
813
873
break ;
814
874
815
875
case 4 :
@@ -826,13 +886,13 @@ int mainThrows(int argc, char * argv[])
826
886
cout << " This PCU profile is not supported on your processor\n " ;
827
887
break ;
828
888
}
829
- printMetrics (getHeader () ,
889
+ printMetrics (header ,
830
890
{
831
891
Metric (" PCUClocks" , getPCUClocks (u, BeforeState[socket], AfterState[socket]), " " ),
832
892
Metric (" OS freq limit cycles" , 100 . * getNormalizedPCUCounter (u, 1 , BeforeState[socket], AfterState[socket]), " %" ),
833
893
Metric (" Power freq limit cycles" , 100 . * getNormalizedPCUCounter (u, 2 , BeforeState[socket], AfterState[socket]), " %" ),
834
894
Metric (" Clipped freq limit cycles" , 100 . * getNormalizedPCUCounter (u, 3 , BeforeState[socket], AfterState[socket]), " %" )
835
- });
895
+ }, outputType );
836
896
break ;
837
897
case 5 :
838
898
metrics.push_back (Metric (" PCUClocks" , getPCUClocks (u, BeforeState[socket], AfterState[socket]), " " ));
@@ -843,7 +903,7 @@ int mainThrows(int argc, char * argv[])
843
903
metrics.push_back (Metric (" UFS transition count" , getUncoreCounter (PCM::PCU_PMU_ID, u, 3 , BeforeState[socket], AfterState[socket]), " " ));
844
904
metrics.push_back (Metric (" UFS transition cycles" , 100 . * getNormalizedPCUCounter (u, 0 , BeforeState[socket], AfterState[socket], m), " %" ));
845
905
}
846
- printMetrics (getHeader () , metrics);
906
+ printMetrics (header , metrics, outputType );
847
907
break ;
848
908
case 6 :
849
909
if (cpu_family_model == PCM::HASWELLX || PCM::BDX_DE == cpu_family_model)
@@ -871,25 +931,25 @@ int mainThrows(int argc, char * argv[])
871
931
metrics.push_back (Metric (" PC6 transitions" , getUncoreCounter (PCM::PCU_PMU_ID, u, 3 , BeforeState[socket], AfterState[socket]), " " ));
872
932
break ;
873
933
}
874
- printMetrics (getHeader () , metrics);
934
+ printMetrics (header , metrics, outputType );
875
935
break ;
876
936
case 7 :
877
937
if (PCM::HASWELLX == cpu_family_model || PCM::BDX_DE == cpu_family_model || PCM::BDX == cpu_family_model) {
878
- printMetrics (getHeader () ,
938
+ printMetrics (header ,
879
939
{
880
940
Metric (" UFS_TRANSITIONS_PERF_P_LIMIT" , getNormalizedPCUCounter (u, 0 , BeforeState[socket], AfterState[socket], m) * 100 ., " %" ),
881
941
Metric (" UFS_TRANSITIONS_IO_P_LIMIT" , getNormalizedPCUCounter (u, 1 , BeforeState[socket], AfterState[socket], m) * 100 ., " %" ),
882
942
Metric (" UFS_TRANSITIONS_UP_RING_TRAFFIC" , getNormalizedPCUCounter (u, 2 , BeforeState[socket], AfterState[socket], m) * 100 ., " %" ),
883
943
Metric (" UFS_TRANSITIONS_UP_STALL_CYCLES" , getNormalizedPCUCounter (u, 3 , BeforeState[socket], AfterState[socket], m) * 100 ., " %" )
884
- });
944
+ }, outputType );
885
945
}
886
946
break ;
887
947
case 8 :
888
948
if (PCM::HASWELLX == cpu_family_model || PCM::BDX_DE == cpu_family_model || PCM::BDX == cpu_family_model) {
889
- printMetrics (getHeader () ,
949
+ printMetrics (header ,
890
950
{
891
951
Metric (" UFS_TRANSITIONS_DOWN" , getNormalizedPCUCounter (u, 0 , BeforeState[socket], AfterState[socket], m) * 100 ., " %" )
892
- });
952
+ }, outputType );
893
953
}
894
954
break ;
895
955
}
@@ -901,13 +961,13 @@ int mainThrows(int argc, char * argv[])
901
961
Metric (" Consumed Joules" , getConsumedJoules (BeforeState[socket], AfterState[socket]), " " ),
902
962
Metric (" Watts" , 1000 . * getConsumedJoules (BeforeState[socket], AfterState[socket]) / double (AfterTime - BeforeTime), " " ),
903
963
Metric (" Thermal headroom below TjMax" , AfterState[socket].getPackageThermalHeadroom (), " °C" )
904
- });
964
+ }, outputType );
905
965
printMetrics (" S" + std::to_string (socket),
906
966
{
907
967
Metric (" Consumed DRAM energy units" , getDRAMConsumedEnergy (BeforeState[socket], AfterState[socket]), " " ),
908
968
Metric (" Consumed DRAM Joules" , getDRAMConsumedJoules (BeforeState[socket], AfterState[socket]), " " ),
909
969
Metric (" DRAM Watts" , 1000 . * getDRAMConsumedJoules (BeforeState[socket], AfterState[socket]) / double (AfterTime - BeforeTime), " " )
910
- });
970
+ }, outputType );
911
971
}
912
972
for (auto instance = 0ULL ; instance < PERF_LIMIT_REASON_TPMI_dies_data.size (); ++instance)
913
973
{
@@ -919,7 +979,7 @@ int mainThrows(int argc, char * argv[])
919
979
{
920
980
metrics.push_back (Metric (PERF_LIMIT_REASON_TPMI::Coarse_Grained_PLR_Bit_Definition_Strings[l], extract_bits (data, l, l) ? true : false , " " ));
921
981
}
922
- printMetrics (" S" + std::to_string (instance) + " D" + std::to_string (die) + " PERF LIMIT REASONS (DIE LEVEL)" , metrics);
982
+ printMetrics (" S" + std::to_string (instance) + " D" + std::to_string (die) + " PERF LIMIT REASONS (DIE LEVEL)" , metrics, outputType );
923
983
}
924
984
}
925
985
for (auto instance = 0ULL ; instance < PERF_LIMIT_REASON_TPMI_modules_data.size (); ++instance)
@@ -960,16 +1020,27 @@ int mainThrows(int argc, char * argv[])
960
1020
metrics.push_back (Metric (std::string (PERF_LIMIT_REASON_TPMI::Coarse_Grained_PLR_Bit_Definition_Strings[PERF_LIMIT_REASON_TPMI::Fine_Grained_PLR_Bit_Definition_Data[l].coarse_grained_mapping ]) + " ." +
961
1021
PERF_LIMIT_REASON_TPMI::Fine_Grained_PLR_Bit_Definition_Data[l].name , fineGrainedData[die][l], " " ));
962
1022
}
963
- printMetrics (" S" + std::to_string (instance) + " D" + std::to_string (die) + " PERF LIMIT REASONS (#CORE MODULES)" , metrics, true );
1023
+ printMetrics (" S" + std::to_string (instance) + " D" + std::to_string (die) + " PERF LIMIT REASONS (#CORE MODULES)" , metrics, outputType, true );
964
1024
}
965
1025
}
1026
+ if (csv)
1027
+ {
1028
+ cout << " \n " ;
1029
+ }
966
1030
};
967
1031
968
- mainLoop ([& ]()
1032
+ auto printLine = [ ]()
969
1033
{
970
1034
cout << " ----------------------------------------------------------------------------------------------\n " ;
1035
+ };
971
1036
972
- if (!csv) cout << flush;
1037
+ mainLoop ([&]()
1038
+ {
1039
+ if (!csv)
1040
+ {
1041
+ printLine ();
1042
+ cout << flush;
1043
+ }
973
1044
974
1045
const auto delay_ms = calibratedSleep (delay, sysCmd, mainLoop, m);
975
1046
@@ -986,14 +1057,23 @@ int mainThrows(int argc, char * argv[])
986
1057
PERF_LIMIT_REASON_TPMI::reset (max_pm_modules);
987
1058
}
988
1059
989
- printAll (delay_ms);
1060
+ if (csv_header)
1061
+ {
1062
+ printAll (delay_ms, Header1);
1063
+ printAll (delay_ms, Header2);
1064
+ csv_header = false ;
1065
+ }
1066
+ printAll (delay_ms, Data);
990
1067
991
1068
swap (BeforeState, AfterState);
992
1069
swap (BeforeTime, AfterTime);
993
1070
swap (beforeSocketState, afterSocketState);
994
1071
995
1072
if (m->isBlocked ()) {
996
- cout << " ----------------------------------------------------------------------------------------------\n " ;
1073
+ if (!csv)
1074
+ {
1075
+ printLine ();
1076
+ }
997
1077
// in case PCM was blocked after spawning child application: break monitoring loop here
998
1078
return false ;
999
1079
}
0 commit comments