| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | #include <cmath>#include <format>#include <MathLogger.h>#ifdef TUTORIAL_USE_SSE2#  include <emmintrin.h>#endifnamespace {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 operationsdouble 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;}// TODO10: Replace this hardcoded sqrtTable with #include <SqrtTable.h>double sqrtTable[] = { 0, 1, 1, 2, 2, 2, 2, 3, 3, 3 };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}}
 |