Browse Source

Implemented SIMD rsqrt.

Branimir Karadžić 8 years ago
parent
commit
c1f8036b70
3 changed files with 53 additions and 18 deletions
  1. 20 1
      include/bx/inline/math.inl
  2. 27 17
      tests/math_bench.cpp
  3. 6 0
      tests/math_test.cpp

+ 20 - 1
include/bx/inline/math.inl

@@ -208,11 +208,30 @@ namespace bx
 #endif // BX_CONFIG_SUPPORTS_SIMD
 	}
 
-	inline float rsqrt(float _a)
+	inline float rsqrtRef(float _a)
 	{
 		return pow(_a, -0.5f);
 	}
 
+	inline float rsqrtSimd(float _a)
+	{
+		const simd128_t aa     = simd_splat(_a);
+		const simd128_t rsqrta = simd_rsqrt(aa);
+		float result;
+		simd_stx(&result, rsqrta);
+
+		return result;
+	}
+
+	inline float rsqrt(float _a)
+	{
+#if BX_CONFIG_SUPPORTS_SIMD
+		return rsqrtSimd(_a);
+#else
+		return rsqrtRef(_a);
+#endif // BX_CONFIG_SUPPORTS_SIMD
+	}
+
 	inline float trunc(float _a)
 	{
 		return float(int(_a) );

+ 27 - 17
tests/math_bench.cpp

@@ -11,7 +11,6 @@
 
 typedef float (*MathFn)(float);
 
-
 template<MathFn mfn>
 float mathTest(const char* _name)
 {
@@ -32,37 +31,48 @@ float mathTest(const char* _name)
 	return result;
 }
 
+float rsqrt(float _a)
+{
+	return 1.0f/::sqrtf(_a);
+}
+
 void math_bench()
 {
 	bx::WriterI* writer = bx::getStdOut();
 	bx::writePrintf(writer, "Math bench\n\n");
 
-	mathTest<  ::sqrtf   >("::sqrtf");
-	mathTest<bx::sqrtRef >("bx::sqrtRef");
-	mathTest<bx::sqrtSimd>("bx::sqrtSimd");
-	mathTest<bx::sqrt    >("bx::sqrt");
+	mathTest<  ::sqrtf    >("::sqrtf");
+	mathTest<bx::sqrtRef  >("bx::sqrtRef");
+	mathTest<bx::sqrtSimd >("bx::sqrtSimd");
+	mathTest<bx::sqrt     >("bx::sqrt");
+
+	bx::writePrintf(writer, "\n");
+	mathTest<  ::rsqrt    >("::rsqrtf");
+	mathTest<bx::rsqrtRef >("bx::sqrtRef");
+	mathTest<bx::rsqrtSimd>("bx::sqrtSimd");
+	mathTest<bx::rsqrt    >("bx::rsqrt");
 
 	bx::writePrintf(writer, "\n");
-	mathTest<  ::sinf   >("::sinf");
-	mathTest<bx::sin    >("bx::sin");
+	mathTest<  ::sinf >("::sinf");
+	mathTest<bx::sin  >("bx::sin");
 
 	bx::writePrintf(writer, "\n");
-	mathTest<  ::asinf  >("::asinf");
-	mathTest<bx::asin   >("bx::asin");
+	mathTest<  ::asinf>("::asinf");
+	mathTest<bx::asin >("bx::asin");
 
 	bx::writePrintf(writer, "\n");
-	mathTest<  ::cosf   >("::cosf");
-	mathTest<bx::cos    >("bx::cos");
+	mathTest<  ::cosf >("::cosf");
+	mathTest<bx::cos  >("bx::cos");
 
 	bx::writePrintf(writer, "\n");
-	mathTest<  ::acosf  >("::acosf");
-	mathTest<bx::acos   >("bx::acos");
+	mathTest<  ::acosf>("::acosf");
+	mathTest<bx::acos >("bx::acos");
 
 	bx::writePrintf(writer, "\n");
-	mathTest<  ::tanf   >("::tanf");
-	mathTest<bx::tan    >("bx::tan");
+	mathTest<  ::tanf >("::tanf");
+	mathTest<bx::tan  >("bx::tan");
 
 	bx::writePrintf(writer, "\n");
-	mathTest<  ::atanf  >("::atanf");
-	mathTest<bx::atan   >("bx::atan");
+	mathTest<  ::atanf>("::atanf");
+	mathTest<bx::atan >("bx::atan");
 }

+ 6 - 0
tests/math_test.cpp

@@ -70,6 +70,12 @@ TEST_CASE("libm", "")
 		REQUIRE(bx::equal(bx::exp(xx), ::expf(xx), 0.00001f) );
 	}
 
+	for (float xx = 0.0f; xx < 100.0f; xx += 0.1f)
+	{
+		bx::writePrintf(writer, "rsqrt(%f) == %f (expected: %f)\n", xx, bx::rsqrt(xx), 1.0f/::sqrtf(xx) );
+		REQUIRE(bx::equal(bx::rsqrt(xx), 1.0f/::sqrtf(xx), 0.00001f) );
+	}
+
 	for (float xx = 0.0f; xx < 100.0f; xx += 0.1f)
 	{
 		bx::writePrintf(writer, "sqrt(%f) == %f (expected: %f)\n", xx, bx::sqrt(xx), ::sqrtf(xx) );