Home | History | Annotate | Download | only in bench
      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 
     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 
     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 
     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 
    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