11package bwapi ;
22
3+ import java .util .ArrayList ;
4+
35/**
46 * Collects various performance metrics.
57 */
68public class PerformanceMetrics {
79
810 /**
9- * Total duration of the frame from JBWAPI's perspective,
10- * exclusive of time modifying shared memory to indicate frame completion.
11- * Likely to be at least a little bit of an undercount from the perspective of BWAPI,
12- * given that the tournament module is timing a superset of JBWAPI's execution time.
11+ * Duration of the frame cycle steps measured by BWAPI,
12+ * from receiving a frame to BWAPI
13+ * to sending commands back
14+ * *exclusive* of the time spent sending commands back.
15+ */
16+ PerformanceMetric frameDurationReceiveToSend ;
17+
18+ /**
19+ * Duration of the frame cycle steps measured by BWAPI,
20+ * from receiving a frame to BWAPI
21+ * to sending commands back
22+ * *inclusive* of the time spent sending commands back.
1323 */
14- PerformanceMetric jbwapiFrameDuration ;
24+ PerformanceMetric frameDurationReceiveToSent ;
1525
1626 /**
17- * Total duration of the frame from JBWAPI's perspective,
18- * inclusive of time modifying shared memory to indicate frame completion.
19- * Likely to be at least a little bit of an undercount from the perspective of BWAPI,
20- * given that the tournament module is timing a superset of JBWAPI's execution time.
27+ * Duration of a frame cycle originating at
28+ * the time when JBWAPI observes a new frame in shared memory.
2129 */
22- PerformanceMetric endToEndFrameDuration ;
30+ PerformanceMetric frameDurationReceiveToReceive ;
2331
2432 /**
2533 * Time spent copying game data from system pipe shared memory to a frame buffer.
@@ -56,9 +64,23 @@ public class PerformanceMetrics {
5664 PerformanceMetric botResponse ;
5765
5866 /**
59- * Time spent waiting for a response from BWAPI; is likely reflective of the performance of any opponent bots.
67+ * Time spent waiting for a response from BWAPI,
68+ * inclusive of the time spent sending the signal to BWAPI
69+ * and the time spent waiting for and receiving it.
6070 */
61- PerformanceMetric bwapiResponse ;
71+ PerformanceMetric communicationSendToReceive ;
72+
73+ /**
74+ * Time spent sending the "frame complete" signal to BWAPI.
75+ * Significant durations would indicate something blocking writes to shared memory.
76+ */
77+ PerformanceMetric communicationSendToSent ;
78+
79+ /**
80+ * Time spent waiting for a "frame ready" signal from BWAPI.
81+ * This time likely additional response time spent by other bots and StarCraft itself.
82+ */
83+ PerformanceMetric communicationListenToReceive ;
6284
6385 /**
6486 * Time bot spends idle.
@@ -79,62 +101,56 @@ public class PerformanceMetrics {
79101 PerformanceMetric excessSleep ;
80102
81103 /**
82- * Instances of System.nanoTime() measuring a longer frame duration with respect to WinAPI's GetTickCount.
104+ * Instances of System.nanoTime() measuring a longer frame duration with respect to WinAPI's GetTickCount which BWAPI uses up to 4.4 .
83105 */
84106 PerformanceMetric positiveTimeDelta ;
85107
86108 /**
87- * Instances of System.nanoTime() measuring a shorter frame duration with respect to WinAPI's GetTickCount.
109+ * Instances of System.nanoTime() measuring a shorter frame duration with respect to WinAPI's GetTickCount which BWAPI uses up to 4.4 .
88110 */
89111 PerformanceMetric negativeTimeDelta ;
90112
91- /**
92- * When Kernel32.INSTANCE.GetTickCount() returns at least one inexplicable value
93- */
94- PerformanceMetric weirdTimeDelta ;
95-
96113 private BWClientConfiguration configuration ;
114+ private ArrayList <PerformanceMetric > performanceMetrics = new ArrayList <>();
97115
98116 PerformanceMetrics (BWClientConfiguration configuration ) {
99117 this .configuration = configuration ;
100118 reset ();
101119 }
102120
103121 public void reset () {
104- jbwapiFrameDuration = new PerformanceMetric ("JBWAPI frame duration" , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
105- endToEndFrameDuration = new PerformanceMetric ("End-to-end frame duration" , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
106- copyingToBuffer = new PerformanceMetric ("Time copying to buffer" , 5 , 10 , 15 , 20 , 25 , 30 );
107- intentionallyBlocking = new PerformanceMetric ("Blocking with full buffer" , 0 );
108- frameBufferSize = new PerformanceMetric ("Frames buffered" , 0 , 1 );
109- framesBehind = new PerformanceMetric ("Frames behind real-time" , 0 , 1 );
110- flushSideEffects = new PerformanceMetric ("Flushing side effects" , 1 , 3 , 5 );
111- botResponse = new PerformanceMetric ("Bot event handlers" , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
112- bwapiResponse = new PerformanceMetric ("Responses from BWAPI" , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
113- botIdle = new PerformanceMetric ("Bot idle" , Long .MAX_VALUE );
114- clientIdle = new PerformanceMetric ("Client idling" , configuration .maxFrameDurationMs );
115- excessSleep = new PerformanceMetric ("Excess sleep" , 1 , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
116- positiveTimeDelta = new PerformanceMetric ("Positive timer delta" , 1 , 2 , 3 , 4 , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
117- negativeTimeDelta = new PerformanceMetric ("Negative timer delta" , 1 , 2 , 3 , 4 , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
118- weirdTimeDelta = new PerformanceMetric ("Weird timer delta" );
122+ performanceMetrics .clear ();
123+ frameDurationReceiveToSend = new PerformanceMetric (this , "Frame duration: Receiving 'frame ready' -> before sending 'frame done'" , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
124+ frameDurationReceiveToSent = new PerformanceMetric (this , "Frame duration: Receiving 'frame ready' -> after sending 'frame done'" , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
125+ frameDurationReceiveToReceive = new PerformanceMetric (this , "Frame duration: From BWAPI receive to BWAPI receive" , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
126+ communicationSendToReceive = new PerformanceMetric (this , "BWAPI duration: Before sending 'frame done' -> After receiving 'frame ready'" , 1 , 3 , 5 , 10 , 15 , 20 , 30 );
127+ communicationSendToSent = new PerformanceMetric (this , "BWAPI duration: Before sending 'frame done' -> After sending 'frame done'" , 1 , 3 , 5 , 10 , 15 , 20 , 30 );
128+ communicationListenToReceive = new PerformanceMetric (this , "BWAPI duration: Before listening for 'frame ready' -> After receiving 'frame ready'" , 1 , 3 , 5 , 10 , 15 , 20 , 30 );
129+ copyingToBuffer = new PerformanceMetric (this , "Copying frame to buffer" , 5 , 10 , 15 , 20 , 25 , 30 );
130+ intentionallyBlocking = new PerformanceMetric (this , "Time holding frame until buffer frees capacity" , 0 );
131+ frameBufferSize = new PerformanceMetric (this , "Frames already buffered when enqueuing a new frame" , 0 , 1 );
132+ framesBehind = new PerformanceMetric (this , "Frames behind real-time when handling events" , 0 , 1 );
133+ flushSideEffects = new PerformanceMetric (this , "Time flushing side effects" , 1 , 3 , 5 );
134+ botResponse = new PerformanceMetric (this , "Duration of bot event handlers" , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
135+ botIdle = new PerformanceMetric (this , "Time bot spent idle" , Long .MAX_VALUE );
136+ clientIdle = new PerformanceMetric (this , "Time client spent waiting for bot" , configuration .maxFrameDurationMs );
137+ excessSleep = new PerformanceMetric (this , "Excess duration of client sleep" , 1 , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
138+ positiveTimeDelta = new PerformanceMetric (this , "Positive timer discrepancy compared to BWAPI" , 1 , 2 , 3 , 4 , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
139+ negativeTimeDelta = new PerformanceMetric (this , "Negative timer discrepancy compared to BWAPI" , 1 , 2 , 3 , 4 , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 85 );
140+ }
141+
142+ void addMetric (PerformanceMetric performanceMetric ) {
143+ performanceMetrics .add (performanceMetric );
119144 }
120145
121146 @ Override
122147 public String toString () {
123- return "Performance metrics:"
124- + "\n " + jbwapiFrameDuration .toString ()
125- + "\n " + endToEndFrameDuration .toString ()
126- + "\n " + copyingToBuffer .toString ()
127- + "\n " + intentionallyBlocking .toString ()
128- + "\n " + frameBufferSize .toString ()
129- + "\n " + framesBehind .toString ()
130- + "\n " + flushSideEffects .toString ()
131- + "\n " + botResponse .toString ()
132- + "\n " + bwapiResponse .toString ()
133- + "\n " + botIdle .toString ()
134- + "\n " + clientIdle .toString ()
135- + "\n " + excessSleep .toString ()
136- + "\n " + positiveTimeDelta .toString ()
137- + "\n " + negativeTimeDelta .toString ()
138- + "\n " + weirdTimeDelta .toString ();
148+ StringBuilder outputBuilder = new StringBuilder ();
149+ outputBuilder .append ("Performance metrics:" );
150+ performanceMetrics .forEach (metric -> {
151+ outputBuilder .append ("\n " );
152+ outputBuilder .append (metric .toString ());
153+ });
154+ return outputBuilder .toString ();
139155 }
140156}
0 commit comments