fork(1) download
  1. #include <iostream>
  2. #include <chrono>
  3. #include <cmath>
  4.  
  5. using namespace std;
  6.  
  7. #define ITERATIONS 5000
  8.  
  9. static double _t;
  10. static double _i;
  11. static double _f;
  12.  
  13. inline double my_fmod( double y, double x ) {
  14. double r;
  15. __asm__ __volatile__ (
  16. "0: \n"
  17. "fprem \n"
  18. "fstsw %%ax \n"
  19. "sahf \n"
  20. "jp 0b \n"
  21. : "=t" (r) : "0" (y), "u" (x) : "ax" );
  22. return r;
  23. }
  24.  
  25. inline double my_modf( double x, double *iptr ) {
  26. double fmod_result = my_fmod( x, 1 );
  27. *iptr = x - fmod_result;
  28. return fmod_result;
  29. }
  30.  
  31. inline double my_floor( double x ) {
  32. double r;
  33. __asm__ __volatile__ (
  34. "mov $0x04, %%ah \n"
  35. "xor %%ecx, %%ecx \n"
  36. "mov %%ah, %%ch \n"
  37. "push %%eax \n"
  38. "fstcw (%%esp) \n"
  39. "mov (%%esp), %%ax \n"
  40. "and $0x03, %%ah \n"
  41. "or %%ecx, %%eax \n"
  42. "mov %%ax, 2(%%esp) \n"
  43. "fldcw 2(%%esp) \n"
  44. "frndint \n"
  45. "fldcw (%%esp) \n"
  46. "pop %%eax \n"
  47. : "=t" (r) : "0" (x) : "ax" );
  48. return r;
  49. }
  50.  
  51.  
  52. void native_floor() {
  53. _i = floor( _t );
  54. _f = (_t - _i) * 0x100000000;
  55. }
  56.  
  57. void custom_floor() {
  58. _i = my_floor( _t );
  59. _f = (_t - _i) * 0x100000000;
  60. }
  61.  
  62. void native_modf() {
  63. _f = modf( _t, &_i );
  64. }
  65.  
  66. void custom_modf() {
  67. _f = my_modf( _t, &_i );
  68. }
  69.  
  70. #define MEASURE( func ) \
  71. a = chrono::system_clock::now(); \
  72. for ( unsigned i = 0; i < ITERATIONS; i++ ) { \
  73. for ( unsigned j = 0; j < ITERATIONS; j++ ) { \
  74. func(); \
  75. } \
  76. } \
  77. b = chrono::system_clock::now(); \
  78. cout << #func << " : " << chrono::duration_cast< chrono::milliseconds >( b - a ).count() << " ms." << endl;
  79.  
  80.  
  81. int main()
  82. {
  83. chrono::system_clock::time_point a, b;
  84.  
  85. _t = (double)(rand() % RAND_MAX) / RAND_MAX * 1000;
  86.  
  87. MEASURE( native_floor );
  88. MEASURE( custom_floor );
  89. MEASURE( native_modf );
  90. MEASURE( custom_modf );
  91.  
  92. return 0;
  93. }
Success #stdin #stdout 2.05s 3340KB
stdin
Standard input is empty
stdout
native_floor : 667 ms.
custom_floor : 548 ms.
native_modf : 596 ms.
custom_modf : 241 ms.