123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- #include <cmath>
- #include <format>
- #include <MathLogger.h>
- #ifdef TUTORIAL_USE_SSE2
- # include <emmintrin.h>
- #endif
- namespace {
- mathlogger::Logger Logger;
- #if defined(TUTORIAL_USE_GNU_BUILTIN)
- typedef double v2df __attribute__((vector_size(16)));
- double gnu_mysqrt(double x)
- {
- v2df root = __builtin_ia32_sqrtsd(v2df{ x, 0.0 });
- double result = root[0];
- Logger.Log(std::format("Computed sqrt of {} to be {} with GNU-builtins\n", x,
- result));
- return result;
- }
- #elif defined(TUTORIAL_USE_SSE2)
- double sse2_mysqrt(double x)
- {
- __m128d root = _mm_sqrt_sd(_mm_setzero_pd(), _mm_set_sd(x));
- double result = _mm_cvtsd_f64(root);
- Logger.Log(
- std::format("Computed sqrt of {} to be {} with SSE2\n", x, result));
- return result;
- }
- #endif
- // a hack square root calculation using simple operations
- double fallback_mysqrt(double x)
- {
- if (x <= 0) {
- return 0;
- }
- double result = x;
- // do ten iterations
- for (int i = 0; i < 10; ++i) {
- if (result <= 0) {
- result = 0.1;
- }
- double delta = x - (result * result);
- result = result + 0.5 * delta / result;
- Logger.Log(std::format("Computing sqrt of {} to be {}\n", x, result));
- }
- return result;
- }
- #include <SqrtTable.h>
- double table_sqrt(double x)
- {
- double result = sqrtTable[static_cast<int>(x)];
- // do ten iterations
- for (int i = 0; i < 10; ++i) {
- if (result <= 0) {
- result = 0.1;
- }
- double delta = x - (result * result);
- result = result + 0.5 * delta / result;
- }
- Logger.Log(
- std::format("Computed sqrt of {} to be {} with TableSqrt\n", x, result));
- return result;
- }
- double mysqrt(double x)
- {
- if (x >= 1 && x < 10) {
- return table_sqrt(x);
- }
- #if defined(TUTORIAL_USE_GNU_BUILTIN)
- return gnu_mysqrt(x);
- #elif defined(TUTORIAL_USE_SSE2)
- return sse2_mysqrt(x);
- #else
- return fallback_mysqrt(x);
- #endif
- }
- }
- namespace mathfunctions {
- double sqrt(double x)
- {
- #ifdef TUTORIAL_USE_STD_SQRT
- return std::sqrt(x);
- #else
- return mysqrt(x);
- #endif
- }
- }
|