static volatile const char *BOINCrcsid="$Id$"; /* * C/C++ Whetstone Benchmark Single or Double Precision * * Original concept Brian Wichmann NPL 1960's * Original author Harold Curnow CCTA 1972 * Self timing versions Roy Longbottom CCTA 1978/87 * Optimisation control Bangor University 1987/90 * C/C++ Version Roy Longbottom 1996 * Compatibility & timers Al Aburto 1996 * ************************************************************ * * Official version approved by: * * Harold Curnow 100421.1615@compuserve.com * * Happy 25th birthday Whetstone, 21 November 1997 */ // Modified a little to work with BOINC // #ifdef _WIN32 #include "boinc_win.h" #endif #ifndef _WIN32 #include #include #include #include #include #endif #include "util.h" #include "cpu_benchmark.h" #define SPDP double // External array; store results here so that optimizing compilers // don't do away with their computation. // suggested by Ben Herndon // double extern_array[12]; // #pragma intrinsic (sin, cos, tan, atan, sqrt, exp, log) void pa(SPDP e[4], SPDP t, SPDP t2) { long j; for(j=0;j<6;j++) { e[0] = (e[0]+e[1]+e[2]-e[3])*t; e[1] = (e[0]+e[1]-e[2]+e[3])*t; e[2] = (e[0]-e[1]+e[2]+e[3])*t; e[3] = (-e[0]+e[1]+e[2]+e[3])/t2; } return; } void po(SPDP e1[4], long j, long k, long l) { e1[j] = e1[k]; e1[k] = e1[l]; e1[l] = e1[j]; return; } void p3(SPDP *x, SPDP *y, SPDP *z, SPDP t, SPDP t1, SPDP t2) { *x = *y; *y = *z; *x = t * (*x + *y); *y = t1 * (*x + *y); *z = (*x + *y)/t2; return; } void whetstone(double& flops) { long n1,n2,n3,n4,n5,n6,n7,n8,i,ix,n1mult; SPDP x,y,z; long j,k,l, jjj; SPDP e1[4]; double startsec, finisec, ws; double KIPS; int xtra, ii; int x100 = 10000; // chosen to make each pass take about 1 sec // on my current computer (2.2 GHz celeron) // Non-critical. extern_array[11] = 1; benchmark_wait_to_start(BM_TYPE_FP); boinc_calling_thread_cpu_time(startsec, ws); SPDP t = 0.49999975; SPDP t0 = t; SPDP t1 = 0.50000025; SPDP t2 = 2.0; n1 = 12*x100; n2 = 14*x100; n3 = 345*x100; n4 = 210*x100; n5 = 32*x100; n6 = 899*x100; n7 = 616*x100; n8 = 93*x100; xtra = 1; n1mult = 10; ii = 0; do { /* Section 1, Array elements */ e1[0] = 1.0; e1[1] = -1.0; e1[2] = -1.0; e1[3] = -1.0; { for (ix=0; ix2) j = jjj; else j = 1; if(l<1) k = 1; else k = jjj; } } } extern_array[5] = (double)j; /* Section 4, Integer arithmetic */ j = long(e1[0]); k = 2; l = 3; { for (ix=0; ix= 1000.0) printf("C Converted Double Precision Whetstones: %.1f MIPS\n", KIPS/1000.0); else printf("C Converted Double Precision Whetstones: %.1f KIPS\n", KIPS); #endif // convert from thousands of instructions a second to instructions a second. flops = KIPS*1000.0; }