| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 | #include <cmath>#include <format>#include <MathLogger.h>// TODO3: If the TUTORIAL_USE_SSE2 definition is set, include//        the <emmintrin.h> headernamespace {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;}double mysqrt(double 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}}
 |