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