11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
80199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger#include "SkBenchmark.h"
90199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger#include "SkFloatBits.h"
100199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger#include "SkRandom.h"
110199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger#include "SkString.h"
120199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
130199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerclass ScalarBench : public SkBenchmark {
140199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    SkString    fName;
150199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    enum { N = 100000 };
160199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerpublic:
170199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    ScalarBench(void* param, const char name[]) : INHERITED(param) {
180199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        fName.printf("scalar_%s", name);
190199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    }
200199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
210199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    virtual void performTest() = 0;
220199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
230199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerprotected:
240199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    virtual int mulLoopCount() const { return 1; }
250199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
260199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    virtual const char* onGetName() {
270199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        return fName.c_str();
280199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    }
290199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
300199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    virtual void onDraw(SkCanvas* canvas) {
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int n = SkBENCHLOOP(N * this->mulLoopCount());
320199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        for (int i = 0; i < n; i++) {
330199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger            this->performTest();
340199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        }
350199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    }
360199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
370199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerprivate:
380199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    typedef SkBenchmark INHERITED;
390199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger};
400199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
410199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger// we want to stop the compiler from eliminating code that it thinks is a no-op
420199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger// so we have a non-static global we increment, hoping that will convince the
430199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger// compiler to execute everything
440199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerint gScalarBench_NonStaticGlobal;
450199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
460199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger#define always_do(pred)                     \
470199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    do {                                    \
480199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        if (pred) {                         \
490199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger            ++gScalarBench_NonStaticGlobal; \
500199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        }                                   \
510199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    } while (0)
520199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
530199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger// having unknown values in our arrays can throw off the timing a lot, perhaps
540199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger// handling NaN values is a lot slower. Anyway, this guy is just meant to put
550199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger// reasonable values in our arrays.
560199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergertemplate <typename T> void init9(T array[9]) {
570199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    SkRandom rand;
580199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    for (int i = 0; i < 9; i++) {
590199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        array[i] = rand.nextSScalar1();
600199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    }
610199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger}
620199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
630199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerclass FloatComparisonBench : public ScalarBench {
640199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerpublic:
650199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    FloatComparisonBench(void* param) : INHERITED(param, "compare_float") {
660199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        init9(fArray);
670199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    }
680199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerprotected:
690199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    virtual int mulLoopCount() const { return 4; }
700199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    virtual void performTest() {
710199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        always_do(fArray[6] != 0.0f || fArray[7] != 0.0f || fArray[8] != 1.0f);
720199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        always_do(fArray[2] != 0.0f || fArray[5] != 0.0f);
730199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    }
740199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerprivate:
750199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    float fArray[9];
760199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    typedef ScalarBench INHERITED;
770199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger};
780199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
790199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerclass ForcedIntComparisonBench : public ScalarBench {
800199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerpublic:
810199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    ForcedIntComparisonBench(void* param)
820199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        : INHERITED(param, "compare_forced_int") {
830199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        init9(fArray);
840199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    }
850199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerprotected:
860199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    virtual int mulLoopCount() const { return 4; }
870199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    virtual void performTest() {
880199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        always_do(SkScalarAs2sCompliment(fArray[6]) |
890199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger                  SkScalarAs2sCompliment(fArray[7]) |
900199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger                  (SkScalarAs2sCompliment(fArray[8]) - kPersp1Int));
910199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger        always_do(SkScalarAs2sCompliment(fArray[2]) |
920199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger                  SkScalarAs2sCompliment(fArray[5]));
930199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    }
940199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerprivate:
950199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    static const int32_t kPersp1Int = 0x3f800000;
960199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    SkScalar fArray[9];
970199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    typedef ScalarBench INHERITED;
980199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger};
990199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
1000199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerstatic SkBenchmark* S0(void* p) { return new FloatComparisonBench(p); }
1010199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerstatic SkBenchmark* S1(void* p) { return new ForcedIntComparisonBench(p); }
1020199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger
1030199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerstatic BenchRegistry gReg0(S0);
1040199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenbergerstatic BenchRegistry gReg1(S1);
105