Experiments on calculating reciprocal of square root
BUG=
R=reed@google.com, rmistry@chromium.org, bsalomon@google.com, tomhudson@chromium.org, tomhudson@google.com
Author: yang.gu@intel.com
Review URL: https://chromiumcodereview.appspot.com/21755002
git-svn-id: http://skia.googlecode.com/svn/trunk@10671 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/bench/MathBench.cpp b/bench/MathBench.cpp
index 32a89d6..c2b600c 100644
--- a/bench/MathBench.cpp
+++ b/bench/MathBench.cpp
@@ -93,44 +93,58 @@
typedef MathBench INHERITED;
};
-class SlowISqrtMathBench : public MathBench {
-public:
- SlowISqrtMathBench(void* param) : INHERITED(param, "slowIsqrt") {}
-protected:
- virtual void performTest(float* SK_RESTRICT dst,
- const float* SK_RESTRICT src,
- int count) {
- for (int i = 0; i < count; ++i) {
- dst[i] = 1.0f / sk_float_sqrt(src[i]);
- }
- }
-private:
- typedef MathBench INHERITED;
-};
+class InvSqrtBench : public SkBenchmark {
+ enum {
+ ARRAY = SkBENCHLOOP(1000),
+ LOOP = SkBENCHLOOP(5000),
+ };
+ float fData[ARRAY];
+ const char *type;
-static inline float SkFastInvSqrt(float x) {
- float xhalf = 0.5f*x;
- int i = *SkTCast<int*>(&x);
- i = 0x5f3759df - (i>>1);
- x = *SkTCast<float*>(&i);
- x = x*(1.5f-xhalf*x*x);
-// x = x*(1.5f-xhalf*x*x); // this line takes err from 10^-3 to 10^-6
- return x;
-}
-
-class FastISqrtMathBench : public MathBench {
public:
- FastISqrtMathBench(void* param) : INHERITED(param, "fastIsqrt") {}
-protected:
- virtual void performTest(float* SK_RESTRICT dst,
- const float* SK_RESTRICT src,
- int count) {
- for (int i = 0; i < count; ++i) {
- dst[i] = SkFastInvSqrt(src[i]);
- }
+ InvSqrtBench(void* param, const char *type)
+ : INHERITED(param)
+ , type(type) {
}
+
+ // just so the compiler doesn't remove our loops
+ virtual void process(int) {}
+
+protected:
+ virtual void onPreDraw() SK_OVERRIDE {
+ SkRandom rand;
+ for (int i = 0; i < ARRAY; ++i) {
+ fData[i] = rand.nextRangeF(0, 10000);
+ }
+
+ fIsRendering = false;
+ }
+
+ virtual void onDraw(SkCanvas*) {
+ float accum = 0;
+
+ if (strcmp(type, "float_slow") == 0) {
+ for (int j = 0; j < LOOP; ++j)
+ for (int i = 0; i < ARRAY; ++i)
+ accum += 1.0f / sk_float_sqrt(fData[i]);
+ } else if (strcmp(type, "float_fast") == 0) {
+ for (int j = 0; j < LOOP; ++j)
+ for (int i = 0; i < ARRAY; ++i)
+ accum += SkFloatInvSqrt(fData[i]);
+ }
+
+ this->process(accum);
+ }
+
+ virtual const char* onGetName() {
+ fName.printf("math_inv_sqrt");
+ fName.appendf("_%s", type);
+ return fName.c_str();
+ }
+
private:
- typedef MathBench INHERITED;
+ SkString fName;
+ typedef SkBenchmark INHERITED;
};
static inline uint32_t QMul64(uint32_t value, U8CPU alpha) {
@@ -523,8 +537,8 @@
///////////////////////////////////////////////////////////////////////////////
DEF_BENCH( return new NoOpMathBench(p); )
-DEF_BENCH( return new SlowISqrtMathBench(p); )
-DEF_BENCH( return new FastISqrtMathBench(p); )
+DEF_BENCH( return new InvSqrtBench(p, "float_slow"); )
+DEF_BENCH( return new InvSqrtBench(p, "float_fast"); )
DEF_BENCH( return new QMul64Bench(p); )
DEF_BENCH( return new QMul32Bench(p); )