poly-eval.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // example code showing effect of pipelining in evaluating polynomial
  2. #include <iostream>
  3. #include <sctl.hpp>
  4. #include <omp.h>
  5. #define CPU_clockrate 3.3 // GHz
  6. template <class Type> void test_polynomial() {
  7. Type a,b,c,d,e,f,g,h; // coefficients
  8. a = 2.3515e-07;
  9. b = 9.8697e-04;
  10. c = -1.8656e-02;
  11. d = 1.0716e-01;
  12. e = -1.1821e-01;
  13. f = -3.9467e-01;
  14. g = -3.8480e-02;
  15. h = 1.0033e+00;
  16. Type x = drand48();
  17. std::cout<<"\n\nEvaluating polynomials using Horner's rule:\n";
  18. double T = -omp_get_wtime();
  19. for (long i = 0; i < 1000000000L; i++) {
  20. x = (((((a*x+b)*x+c)*x+d)*x+e)*x+f*x+g)*x+h;
  21. }
  22. T += omp_get_wtime();
  23. std::cout<<"T = "<< T <<'\n';
  24. std::cout<<"cycles/iter = "<< CPU_clockrate*T <<'\n';
  25. std::cout<<"\n\nEvaluating polynomials using Estrin's method:\n";
  26. T = -omp_get_wtime();
  27. for (long i = 0; i < 1000000000L; i++) {
  28. Type x2 = x * x;
  29. Type x4 = x2 * x2;
  30. x = ((a*x+b)*x2+(c*x+d))*x4+(e*x+f)*x2+(g*x+h);
  31. }
  32. T += omp_get_wtime();
  33. std::cout<<"T = "<< T <<'\n';
  34. std::cout<<"cycles/iter = "<< CPU_clockrate*T <<'\n';
  35. std::cout<<"\n\nEvaluating polynomials using Estrin's method (unrolled):\n";
  36. T = -omp_get_wtime();
  37. for (long i = 0; i < 1000000000L; i++) {
  38. Type x2 = x * x;
  39. Type x4 = x2 * x2;
  40. Type u = a * x + b;
  41. Type v = c * x + d;
  42. Type w = e * x + f;
  43. Type p = g * x + h;
  44. Type q = u * x2 + v;
  45. Type r = w * x2 + p;
  46. x = q * x4 + r;
  47. }
  48. T += omp_get_wtime();
  49. std::cout<<"T = "<< T <<'\n';
  50. std::cout<<"cycles/iter = "<< CPU_clockrate*T <<'\n';
  51. std::cout<<"Result = "<<x<<"\n\n\n";
  52. }
  53. int main(int argc, char** argv) {
  54. std::cout<<"\n\nCPU clockrate = "<<CPU_clockrate<<"\n";
  55. test_polynomial<double>(); // scalar
  56. //test_polynomial<sctl::Vec<double,8>>(); // vectorized
  57. return 0;
  58. }