#include <iostream>
#include <chrono>
#include <cmath>
using namespace std;
#define ITERATIONS 5000
static double _t;
static double _i;
static double _f;
inline double my_fmod( double y, double x ) {
double r;
__asm__ __volatile__ (
"0: \n"
"fprem \n"
"fstsw %%ax \n"
"sahf \n"
"jp 0b \n"
: "=t" (r) : "0" (y), "u" (x) : "ax" );
return r;
}
inline double my_modf( double x, double *iptr ) {
double fmod_result = my_fmod( x, 1 );
*iptr = x - fmod_result;
return fmod_result;
}
inline double my_floor( double x ) {
double r;
__asm__ __volatile__ (
"mov $0x04, %%ah \n"
"xor %%ecx, %%ecx \n"
"mov %%ah, %%ch \n"
"push %%eax \n"
"fstcw (%%esp) \n"
"mov (%%esp), %%ax \n"
"and $0x03, %%ah \n"
"or %%ecx, %%eax \n"
"mov %%ax, 2(%%esp) \n"
"fldcw 2(%%esp) \n"
"frndint \n"
"fldcw (%%esp) \n"
"pop %%eax \n"
: "=t" (r) : "0" (x) : "ax" );
return r;
}
void native_floor() {
_i = floor( _t );
_f = (_t - _i) * 0x100000000;
}
void custom_floor() {
_i = my_floor( _t );
_f = (_t - _i) * 0x100000000;
}
void native_modf() {
_f = modf( _t, &_i );
}
void custom_modf() {
_f = my_modf( _t, &_i );
}
#define MEASURE( func ) \
a = chrono::system_clock::now(); \
for ( unsigned i = 0; i < ITERATIONS; i++ ) { \
for ( unsigned j = 0; j < ITERATIONS; j++ ) { \
func(); \
} \
} \
b = chrono::system_clock::now(); \
cout << #func << " : " << chrono::duration_cast< chrono::milliseconds >( b - a ).count() << " ms." << endl;
int main()
{
chrono::system_clock::time_point a, b;
_t = (double)(rand() % RAND_MAX) / RAND_MAX * 1000;
MEASURE( native_floor );
MEASURE( custom_floor );
MEASURE( native_modf );
MEASURE( custom_modf );
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8Y21hdGg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSBJVEVSQVRJT05TIDUwMDAKCnN0YXRpYyBkb3VibGUJX3Q7CnN0YXRpYyBkb3VibGUJX2k7CnN0YXRpYyBkb3VibGUJX2Y7CgppbmxpbmUgZG91YmxlIG15X2Ztb2QoIGRvdWJsZSB5LCBkb3VibGUgeCApIHsKCWRvdWJsZSByOwoJX19hc21fXyBfX3ZvbGF0aWxlX18gKAoJCSIwOgkJCQlcbiIKCQkiZnByZW0JCQlcbiIKCQkiZnN0c3cJJSVheAlcbiIKCQkic2FoZgkJCVxuIgoJCSJqcAkJMGIJCVxuIgoJCTogIj10IiAocikgOiAiMCIgKHkpLCAidSIgKHgpIDogImF4IiApOwoJcmV0dXJuIHI7Cn0KCmlubGluZSBkb3VibGUgbXlfbW9kZiggZG91YmxlIHgsIGRvdWJsZSAqaXB0ciApIHsKCWRvdWJsZSBmbW9kX3Jlc3VsdCA9IG15X2Ztb2QoIHgsIDEgKTsKCSppcHRyID0geCAtIGZtb2RfcmVzdWx0OwoJcmV0dXJuIGZtb2RfcmVzdWx0Owp9CgppbmxpbmUgZG91YmxlIG15X2Zsb29yKCBkb3VibGUgeCApIHsKCWRvdWJsZSByOwoJX19hc21fXyBfX3ZvbGF0aWxlX18gKAoJCSJtb3YJJDB4MDQsICUlYWgJCVxuIgoJCSJ4b3IJJSVlY3gsICUlZWN4CVxuIgoJCSJtb3YJJSVhaCwgJSVjaAkJXG4iCgkJInB1c2gJJSVlYXgJCQlcbiIKCQkiZnN0Y3cJKCUlZXNwKQkJCVxuIgoJCSJtb3YJKCUlZXNwKSwgJSVheAlcbiIKCQkiYW5kCSQweDAzLCAlJWFoCQlcbiIKCQkib3IJCSUlZWN4LCAlJWVheAlcbiIKCQkibW92CSUlYXgsIDIoJSVlc3ApCVxuIgoJCSJmbGRjdwkyKCUlZXNwKQkJXG4iCgkJImZybmRpbnQJCQkJXG4iCgkJImZsZGN3CSglJWVzcCkJCQlcbiIKCQkicG9wCSUlZWF4CQkJXG4iCgkJOiAiPXQiIChyKSA6ICIwIiAoeCkgOiAiYXgiICk7CglyZXR1cm4gcjsKfQoKCnZvaWQgbmF0aXZlX2Zsb29yKCkgewoJX2kgPSBmbG9vciggX3QgKTsKCV9mID0gKF90IC0gX2kpICogMHgxMDAwMDAwMDA7Cn0KCnZvaWQgY3VzdG9tX2Zsb29yKCkgewoJX2kgPSBteV9mbG9vciggX3QgKTsKCV9mID0gKF90IC0gX2kpICogMHgxMDAwMDAwMDA7Cn0KCnZvaWQgbmF0aXZlX21vZGYoKSB7CglfZiA9IG1vZGYoIF90LCAmX2kgKTsKfQoKdm9pZCBjdXN0b21fbW9kZigpIHsKCV9mID0gbXlfbW9kZiggX3QsICZfaSApOwp9CgojZGVmaW5lIE1FQVNVUkUoIGZ1bmMgKQkJCQkJCQkJCQlcCglhID0gY2hyb25vOjpzeXN0ZW1fY2xvY2s6Om5vdygpOwkJCQkJCVwKCWZvciAoIHVuc2lnbmVkIGkgPSAwOyBpIDwgSVRFUkFUSU9OUzsgaSsrICkgewkJCVwKCQlmb3IgKCB1bnNpZ25lZCBqID0gMDsgaiA8IElURVJBVElPTlM7IGorKyApIHsJCVwKCQkJZnVuYygpOwkJCQkJCQkJCQkJXAoJCX0JCQkJCQkJCQkJCQkJXAoJfQkJCQkJCQkJCQkJCQkJXAoJYiA9IGNocm9ubzo6c3lzdGVtX2Nsb2NrOjpub3coKTsJCQkJCQlcCgljb3V0IDw8ICNmdW5jIDw8ICIgOiAiIDw8IGNocm9ubzo6ZHVyYXRpb25fY2FzdDwgY2hyb25vOjptaWxsaXNlY29uZHMgPiggYiAtIGEgKS5jb3VudCgpIDw8ICIgbXMuIiA8PCBlbmRsOwoKCmludCBtYWluKCkKewoJY2hyb25vOjpzeXN0ZW1fY2xvY2s6OnRpbWVfcG9pbnQgYSwgYjsKCglfdCA9IChkb3VibGUpKHJhbmQoKSAlIFJBTkRfTUFYKSAvIFJBTkRfTUFYICogMTAwMDsKCglNRUFTVVJFKCBuYXRpdmVfZmxvb3IgKTsKCU1FQVNVUkUoIGN1c3RvbV9mbG9vciApOwoJTUVBU1VSRSggbmF0aXZlX21vZGYgKTsKCU1FQVNVUkUoIGN1c3RvbV9tb2RmICk7CgoJcmV0dXJuIDA7Cn0=