• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2012 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #include "TimerData.h"
9 
10 #include "BenchTimer.h"
11 #include <limits>
12 
13 using namespace std;
14 
TimerData(int maxNumTimings)15 TimerData::TimerData(int maxNumTimings)
16 : fMaxNumTimings(maxNumTimings)
17 , fCurrTiming(0)
18 , fWallTimes(maxNumTimings)
19 , fTruncatedWallTimes(maxNumTimings)
20 , fCpuTimes(maxNumTimings)
21 , fTruncatedCpuTimes(maxNumTimings)
22 , fGpuTimes(maxNumTimings){
23 }
24 
appendTimes(BenchTimer * timer)25 bool TimerData::appendTimes(BenchTimer* timer) {
26     SkASSERT(timer != NULL);
27     if (fCurrTiming >= fMaxNumTimings) {
28         return false;
29     }
30 
31     fWallTimes[fCurrTiming] = timer->fWall;
32     fTruncatedWallTimes[fCurrTiming] = timer->fTruncatedWall;
33     fCpuTimes[fCurrTiming] = timer->fCpu;
34     fTruncatedCpuTimes[fCurrTiming] = timer->fTruncatedCpu;
35     fGpuTimes[fCurrTiming] = timer->fGpu;
36 
37     ++fCurrTiming;
38 
39     return true;
40 }
41 
getResult(const char * doubleFormat,Result result,const char * configName,uint32_t timerFlags,int itersPerTiming)42 SkString TimerData::getResult(const char* doubleFormat,
43                               Result result,
44                               const char *configName,
45                               uint32_t timerFlags,
46                               int itersPerTiming) {
47     SkASSERT(itersPerTiming >= 1);
48 
49     if (!fCurrTiming) {
50         return SkString("");
51     }
52 
53     int numTimings = fCurrTiming;
54 
55     SkString wallStr(" msecs = ");
56     SkString truncWallStr(" Wmsecs = ");
57     SkString cpuStr(" cmsecs = ");
58     SkString truncCpuStr(" Cmsecs = ");
59     SkString gpuStr(" gmsecs = ");
60 
61     double wallMin = std::numeric_limits<double>::max();
62     double truncWallMin = std::numeric_limits<double>::max();
63     double cpuMin = std::numeric_limits<double>::max();
64     double truncCpuMin = std::numeric_limits<double>::max();
65     double gpuMin = std::numeric_limits<double>::max();
66 
67     double wallSum = 0;
68     double truncWallSum = 0;
69     double cpuSum = 0;
70     double truncCpuSum = 0;
71     double gpuSum = 0;
72 
73     for (int i = 0; i < numTimings; ++i) {
74         if (kPerIter_Result == result) {
75             wallStr.appendf(doubleFormat, fWallTimes[i] / itersPerTiming);
76             truncWallStr.appendf(doubleFormat, fTruncatedWallTimes[i] / itersPerTiming);
77             cpuStr.appendf(doubleFormat, fCpuTimes[i] / itersPerTiming);
78             truncCpuStr.appendf(doubleFormat, fTruncatedCpuTimes[i] / itersPerTiming);
79             gpuStr.appendf(doubleFormat, fGpuTimes[i] / itersPerTiming);
80 
81             if (i != numTimings - 1) {
82                 static const char kSep[] = ", ";
83                 wallStr.append(kSep);
84                 truncWallStr.append(kSep);
85                 cpuStr.append(kSep);
86                 truncCpuStr.append(kSep);
87                 gpuStr.append(kSep);
88             }
89         } else if (kMin_Result == result) {
90             wallMin = SkTMin(wallMin, fWallTimes[i]);
91             truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]);
92             cpuMin = SkTMin(cpuMin, fCpuTimes[i]);
93             truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]);
94             gpuMin = SkTMin(gpuMin, fGpuTimes[i]);
95         } else {
96             SkASSERT(kAvg_Result == result);
97             wallSum += fWallTimes[i];
98             truncWallSum += fTruncatedWallTimes[i];
99             cpuSum += fCpuTimes[i];
100             truncCpuSum += fTruncatedCpuTimes[i];
101         }
102 
103         // We always track the GPU sum because whether it is non-zero indicates if valid gpu times
104         // were recorded at all.
105         gpuSum += fGpuTimes[i];
106     }
107 
108     if (kMin_Result == result) {
109         wallStr.appendf(doubleFormat, wallMin / itersPerTiming);
110         truncWallStr.appendf(doubleFormat, truncWallMin / itersPerTiming);
111         cpuStr.appendf(doubleFormat, cpuMin / itersPerTiming);
112         truncCpuStr.appendf(doubleFormat, truncCpuMin / itersPerTiming);
113         gpuStr.appendf(doubleFormat, gpuMin / itersPerTiming);
114     } else if (kAvg_Result == result) {
115         int divisor = numTimings * itersPerTiming;
116         wallStr.appendf(doubleFormat, wallSum / divisor);
117         truncWallStr.appendf(doubleFormat, truncWallSum / divisor);
118         cpuStr.appendf(doubleFormat, cpuSum / divisor);
119         truncCpuStr.appendf(doubleFormat, truncCpuSum / divisor);
120         gpuStr.appendf(doubleFormat, gpuSum / divisor);
121     }
122 
123     SkString str;
124     str.printf("  %4s:", configName);
125     if (timerFlags & kWall_Flag) {
126         str += wallStr;
127     }
128     if (timerFlags & kTruncatedWall_Flag) {
129         str += truncWallStr;
130     }
131     if (timerFlags & kCpu_Flag) {
132         str += cpuStr;
133     }
134     if (timerFlags & kTruncatedCpu_Flag) {
135         str += truncCpuStr;
136     }
137     if ((timerFlags & kGpu_Flag) && gpuSum > 0) {
138         str += gpuStr;
139     }
140     return str;
141 }
142 
getJSON(uint32_t timerFlags,Result result,int itersPerTiming)143 Json::Value TimerData::getJSON(uint32_t timerFlags,
144                                Result result,
145                                int itersPerTiming) {
146     SkASSERT(itersPerTiming >= 1);
147     Json::Value dataNode;
148     Json::Value wallNode, truncWall, cpuNode, truncCpu, gpuNode;
149     if (!fCurrTiming) {
150         return dataNode;
151     }
152 
153     int numTimings = fCurrTiming;
154 
155     double wallMin = std::numeric_limits<double>::max();
156     double truncWallMin = std::numeric_limits<double>::max();
157     double cpuMin = std::numeric_limits<double>::max();
158     double truncCpuMin = std::numeric_limits<double>::max();
159     double gpuMin = std::numeric_limits<double>::max();
160 
161     double wallSum = 0;
162     double truncWallSum = 0;
163     double cpuSum = 0;
164     double truncCpuSum = 0;
165     double gpuSum = 0;
166 
167     for (int i = 0; i < numTimings; ++i) {
168         if (kPerIter_Result == result) {
169             wallNode.append(fWallTimes[i] / itersPerTiming);
170             truncWall.append(fTruncatedWallTimes[i] / itersPerTiming);
171             cpuNode.append(fCpuTimes[i] / itersPerTiming);
172             truncCpu.append(fTruncatedCpuTimes[i] / itersPerTiming);
173             gpuNode.append(fGpuTimes[i] / itersPerTiming);
174         } else if (kMin_Result == result) {
175             wallMin = SkTMin(wallMin, fWallTimes[i]);
176             truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]);
177             cpuMin = SkTMin(cpuMin, fCpuTimes[i]);
178             truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]);
179             gpuMin = SkTMin(gpuMin, fGpuTimes[i]);
180         } else {
181             SkASSERT(kAvg_Result == result);
182             wallSum += fWallTimes[i];
183             truncWallSum += fTruncatedWallTimes[i];
184             cpuSum += fCpuTimes[i];
185             truncCpuSum += fTruncatedCpuTimes[i];
186         }
187 
188         // We always track the GPU sum because whether it is non-zero indicates if valid gpu times
189         // were recorded at all.
190         gpuSum += fGpuTimes[i];
191     }
192 
193     if (kMin_Result == result) {
194         wallNode.append(wallMin / itersPerTiming);
195         truncWall.append(truncWallMin / itersPerTiming);
196         cpuNode.append(cpuMin / itersPerTiming);
197         truncCpu.append(truncCpuMin / itersPerTiming);
198         gpuNode.append(gpuMin / itersPerTiming);
199     } else if (kAvg_Result == result) {
200         int divisor = numTimings * itersPerTiming;
201         wallNode.append(wallSum / divisor);
202         truncWall.append(truncWallSum / divisor);
203         cpuNode.append(cpuSum / divisor);
204         truncCpu.append(truncCpuSum / divisor);
205         gpuNode.append(gpuSum / divisor);
206     }
207 
208     if (timerFlags & kWall_Flag) {
209         dataNode["wall"] = wallNode;
210     }
211     if (timerFlags & kTruncatedWall_Flag) {
212         dataNode["truncWall"] = truncWall;
213     }
214     if (timerFlags & kCpu_Flag) {
215         dataNode["cpu"] = cpuNode;
216     }
217     if (timerFlags & kTruncatedCpu_Flag) {
218         dataNode["trucCpu"] = truncCpu;
219     }
220     if ((timerFlags & kGpu_Flag) && gpuSum > 0) {
221         dataNode["gpu"] = gpuNode;
222     }
223     return dataNode;
224 }
225