#include #include #include #include unsigned sqrt_fpu1(long l) { if (l == 0) return 0; double f_rslt = sqrt(l); unsigned rslt = (int)f_rslt; if (!(f_rslt - rslt < .5)) rslt ++; return rslt; } unsigned sqrt_cpu1(long l) { long temp; unsigned div, rslt = l; if (l <= 0) return 0; else if (l & 0xFFFF0000L) if (l & 0xFF000000L) div = 0x3FFF; else div = 0x3FF; else if (l & 0x0FF00L) div = 0x3F; else div = (l > 4) ? 0x7 : l; while (1) { temp = l / div + div; div = temp >> 1; div += temp & 1; if (rslt > div) rslt = div; else { if (l / rslt == rslt - 1 && l % rslt == 0) rslt--; break; } } return (unsigned)rslt; } unsigned sqrt_cpu2(long l) { if (l <= 0) return 0; long rslt = l, div = l; while (1) { div = (l / div + div) / 2; if (rslt > div) rslt = div; else break; } return (unsigned)rslt; } unsigned sqrt_cpu3(long l) { unsigned div = 1; unsigned rslt = 0; while (l > 0) { l-= div, div += 2; rslt += l < 0 ? 0 : 1; } return rslt; } unsigned sqrt_cpu4(long l) { unsigned div = 1, rslt = 0; while (l > 0) { l-= div, div += 2; rslt += l < 0 ? 0 : 1; } if (l != 0) rslt++; return rslt; } #define steps 1000 #define range1 1000L #define range2 10000L #define range3 100000L #define count 2000 double times[3][3]; void CalcTime() { long l; int i; time_t first, second; printf("testing range1=[%lu..%lu]...\n", 0L, range1); printf("fpu1...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = 0l; l < range1; l += range1 / steps) sqrt_fpu1(l); second = time(NULL); times[0][0] = difftime(second, first); printf("cpu1...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = 0l; l < range1; l += range1 / steps) sqrt_cpu1(l); second = time(NULL); times[0][1] = difftime(second, first); printf("cpu2...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = 0l; l < range1; l += range1 / steps) sqrt_cpu2(l); second = time(NULL); times[0][2] = difftime(second, first); printf("testing range2=[%lu..%lu]...\n", range1, range2); printf("fpu1...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = range1; l < range2; l += (range2 - range1) / steps) sqrt_fpu1(l); second = time(NULL); times[1][0] = difftime(second, first); printf("cpu1...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = range1; l < range2; l += (range2 - range1) / steps) sqrt_cpu1(l); second = time(NULL); times[1][1] = difftime(second, first); printf("cpu2...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = range1; l < range2; l += (range2 - range1) / steps) sqrt_cpu2(l); second = time(NULL); times[1][2] = difftime(second, first); printf("testing range3=[%lu..%lu]...\n", range2, range3); printf("fpu1...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = range2; l < range3; l += (range3 - range2) / steps) sqrt_fpu1(l); second = time(NULL); times[2][0] = difftime(second, first); printf("cpu1...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = range2; l < range3; l += (range3 - range2) / steps) sqrt_cpu1(l); second = time(NULL); times[2][1] = difftime(second, first); printf("cpu2...\n"); first = time(NULL); for (i = 0; i < count; i++) for (l = range2; l < range3; l += (range3 - range2) / steps) sqrt_cpu2(l); second = time(NULL); times[2][2] = difftime(second, first); printf("Done.\n"); printf("range\t\t fpu1\t cpu1\t cpu2\n"); printf( "%lu\t\t%5.3f\t%5.3f\t%5.3f\n", range1, times[0][0], times[0][1], times[0][2] ); printf( "%lu\t\t%5.3f\t%5.3f\t%5.3f\n", range2, times[1][0], times[1][1], times[1][2] ); printf( "%lu\t\t%5.3f\t%5.3f\t%5.3f\n", range3, times[2][0], times[2][1], times[2][2] ); } typedef unsigned (*sqrt_func)(long L); void ViewDifferents(long rang1, long rang2, unsigned step, sqrt_func fpsqrt) { unsigned long l; unsigned rf, ri; printf("testing with range[%lu..%lu]\n", rang1, rang2); for (l = rang1; l < rang2; l += (rang2 - rang1) / step) { rf = sqrt_fpu1(l); ri = (*fpsqrt)(l); if (rf != ri) printf("sqrt(%lu) %u %u %6.2f\n", l, rf, ri, sqrt(l)); } printf("Done.\n"); } void main() { ViewDifferents(0, 1000, 1000, sqrt_cpu1); CalcTime(); while (!kbhit()); }