/* Machine Description primes reals lines c lines f files estpi 1 estpi 2 estpi 4 Compiler Description 10^6 500 5000 20000 20 500 10^9 10^9 10^9 Environment Description (secs) (secs) (secs) (secs) (secs) (secs) (secs) (secs) ====================================== ======= ======= ======= ======= ======= ======= ======= ======= MacBook Pro (CoreDuo 2.16GHz, 1.0GB) Gnu C (gcc 4.0.2; Xcode 2.2.3) Mac OS X 10.4.6 5.7 3.7 5.2 1.4 4.1 15.2 7.6 7.6 Win-XP Pro; Parallels 6.4 7.7 523.3 2.3 5.6 17.3 17.2 17.6 Win-XP Pro; Boot Camp 6.3 9.6 84.9 2.7 2.7 15.7 7.8 7.7 iMac (Intel CoreDuo 1.83GHz, 512MB) Gnu C (gcc 4.0.1; Xcode 2.2.1) Mac OS X 10.4.6 6.6 8.2 5.4 1.3 3.9 17.5 8.9 8.9 Thinkmate Z71V (Pent.M 1.73GHz) MS VC++ 6.0 (12.00.8804; Pent. code) Win-XP Home; Command Window 7.7 8.6 N 3.8 8.6 19.0 19.0 19.0 Gnu C (gcc 3.4.4) Cygwin Win-XP Home; Cygwin Bash Window 8.1 5.0 N 3.3 7.5 19.6 19.6 19.6 Gnu C (gcc 4.0.2) Linux (SuSE 10.0); XTerm 8.1 5.0 N 0.6 0.5 22.3 22.3 22.3 PowerMac G5 (PPC970 2.0GHz Dual) Gnu C (gcc 3.3) Mac OS X 10.3; Terminal (2 CPU) 10.8 3.9 19.1 1.2 2.1 18.9 9.5 9.6 Mac OS X 10.3; Terminal (1 CPU) 10.8 4.0 30.3 1.2 1.8 19.1 19.1 19.1 Opteron 2.0GHz Dual MS VC++ 8.0 (14.00.50727.42 AMDx64) Win-XPx64; Command Window (2 CPU) 10.9 1.8 37.5 1.6 2.3 8.8 4.4 4.4 MS VC++ 6.0 (12.00.8804; Pent. code) Win-XPx64; Command Window (2 CPU) 11.2 3.7 37.5 1.5 3.5 9.7 4.8 4.8 Gnu C (gcc 3.4.4; 32-bit code) Cygwin Win-XPx64; Command Window (2 CPU) 11.4 2.1 N 3.1 3.6 8.5 4.2 4.3 Gnu C (gcc 4.0.2) Linux (Fedora4/x64); XTerm (2 CPU) 19.2 1.7 N 0.6 0.4 8.9 4.5 4.4 PowerBook G4 Ti 15" (G4 1.0GHz) Metrowerks CWPro 6 Mac OS 9.2.2 12.5 33.7 617.0 14.6 25.8 79.3 79.4 79.4 Gnu C (gcc 3) Mac OS X 10.2.5 12.6 34.0 35.9 3.4 2.3 79.0 79.0 79.0 Gateway 400SD4 (Pent.4 2.336GHz) MS VC++ 6.0 (12.00.8804; Pent. code) Win-XP Home; Command Window 12.7 2.0 127.8 7.4 6.5 15.9 15.9 15.9 Compaq Evo N800w (Pent.4 2.20GHz) MS VC++ 6.0 (12.00.8804; Pent. code) Win-2K Pro; Command Window 14.0 2.2 72.1 9.9 15.9 17.7 17.6 17.7 Athlon XP 1.679GHz (128k L1, 256k L2) Gnu C (gcc 3.2 20020903) Linux (2.4.18-14); Console 14.6 2.8 10.9 1.2 0.7 12.6 12.6 12.6 Dell Inspiron 1100 (Cel.II 2.0GHz) MS VC++ 6.0 (12.00.8804; Pent. code) Win-XP Home; Command Window 15.4 2.5 263.0 6.2 17.1 19.3 19.3 19.3 Celeron II 1.20GHz (128k L1, 256k L2) Gnu C (gcc 2.95.3) Linux (2.4.10); XTerm 16.5 15.1 22.1 1.3 0.6 40.4 31.4 31.4 Gnu C (gcc 2.95.3-5) Cygwin Win-ME; Command Window 16.8 15.2 506.0 6.4 5.7 26.6 26.7 26.7 MS VC++ 6.0 (12.00.8804; Pent. code) Win-ME; Command Window 16.7 12.9 242.5 4.8 3.5 27.1 27.1 27.1 Pent.IIIeb 933MHz Dual (256k cache) Gnu C (gcc 2.96) Linux (2.4.10); XTerm (2 CPU) 19.7 19.4 7.8 1.9 0.7 39.6 19.8 19.8 Gnu C (gcc 2.95.3-5) Cygwin Win-2K; Command Window (2 CPU) 19.7 20.0 230.2 6.1 11.0 33.2 16.6 16.6 MS VC++ 6.0 (12.00.8804; Pent. code) Win-2K; Command Window (2 CPU) 21.0 15.8 230.3 4.5 4.8 33.9 16.9 17.0 Win-2K; Command Window (1 CPU) 21.0 15.8 230.2 4.6 5.2 33.9 33.9 33.9 Micron Millennia (Pent.III 1.0GHz) MS VC++ 6.0 (Pent. code) Win-ME; Command Window 20.9 15.8 434.2 4.9 27.6 33.5 N N Toshiba TECRA 8100 (Pent.III 747MHz) Gnu C (gcc 2.95.3-5) Cygwin Win-NT; Command Window 24.8 25.1 N 22.5 22.3 41.8 41.8 41.7 MS VC++ 6.0 (12.00.8804; Pent. code) Win-NT; Command Window 26.7 20.0 N 20.8 13.6 43.0 42.9 42.9 iBook SE (PPC G3 466MHz, 256k L2) Metrowerks CWPro 5.3 (PPC code) Mac OS 9.0.4; SIOUX (w/o pwr mgt) 29.2 54.7 F 24.5 109.9 131.7 132.0 132.0 Mac OS 9.0.4; SIOUX (with pwr mgt) N N N N N 358.9 258.5 201.8 Gnu C (gcc 2.95.2) PPC Linux (2.4.2); XTerm 29.3 60.2 613.1 3.1 2.8 125.3 124.6 124.7 Mac G4 (PPC G4 450MHz, 1M L2, AGP) Metrowerks CWPro 5.3 (PPC code) Mac OS 9.0.4; SIOUX Console 30.1 51.4 N 18.4 39.8 134.0 134.0 134.7 cc Mac OS X; Terminal 30.9 187.4 92.4 12.2 25 126.7 N N Gnu C (gcc 2.95.2) Mac OS X 10.1; Terminal 31.8 199.9 119.7 4.1 7.3 130.5 130.6 130.8 NetworkEngines (Pent.III 600MHz Dual) Gnu C (gcc 2.95.3-5) Cygwin Win-2K; Command Window (2 CPU) 30.9 31.4 N 12.2 22.5 52.1 26.1 26.1 MS VC++ 6.0 (12.00.8804; Pent. code) Win-2K; Command Window (2 CPU) 33.0 24.8 N 11.8 14.0 53.2 26.6 26.7 Dell Inspiron 7500 (Pent.III 500MHz) MS VC++ 6.0 (Pent. code) Win-NT; Command Window 39.9 29.8 N 24.1 20.5 64.6 N N Tiger (Pent.II 400MHz Dual) Gnu C (gcc 2.95.3-5) Cygwin Win-NT; Command Window (2 CPU) 46.0 39.7 N 25.2 17.0 77.5 39.1 39.2 MS VC++ 6.0 (12.00.8804; Pent. code) Win-NT; Command Window (2 CPU) 49.1 36.9 N 20.3 8.5 78.8 39.7 39.7 CompUSA K6-2 300MHz MS VC++ 6.0 (12.00.8804; Pent. code) Win-98; Command Window 50.2 56.7 1037 32.9 15.7 182.1 182.2 182.2 Gnu C (gcc 2.95.3-5) Cygwin Win-98; Command Window 55.1 71.7 13690 36.7 49.3 178.7 178.8 178.8 Mac 9600/233 (PPC 604e, 512k cache) Metrowerks CW 9 (PPC/604 code) Mac OS; SIOUX Console 61 117 N 81 N N N N Mac 8500 (Newertech-233, 604e, 256k) Metrowerks CWPro 4 (PPC code) Mac OS 8.6; SIOUX Console 63.7 105.1 6010 58.4 285.0 296.1 286.6 285.8 Mac OS 8.6 (w/VM); SIOUX Console 64.3 105.5 6090 63.3 272.7 296.9 287.5 287.0 Pent.II 300MHz (512k cache) MS VC++ 5.0 (Pent. code) Win-NT; Command Window 65 49 288 21 30 N N N Mac 3400c/240 (PPC 603ev, 256k cache) Metrowerks CWPro 5.3 (PPC code) Mac OS 7.6; SIOUX (w/o pwr mgt) 65.6 145.6 N N N N N N Gnu C (gcc 2.95.2) PPC Linux (2.2.18); XTerm 66.3 139.1 483.7 15.0 6.4 265.0 264.9 266.0 Metrowerks CW 12 (PPC/603 code) Mac OS; MSL (w/o power cycling) 66 147 N 67 110 N N N Mac OS; MSL (with power cycling) 483 360 N 66 132 N N N ETO 23 MrC CW 11 Plug-in (PPC/603) Mac OS; SIOUX Console 110 N N N N N N N MS VC++ 2.0 (Pent. code) Virtual PC 1.0 (Win-95; Cmd Wnd) 162 408 22900 609 335 N N N Metrowerks CW 11 (PPC/603 code) Mac OS; MSL 478 517 N 63 N N N N Metrowerks CW 9 (PPC/603 code) Mac OS; SIOUX Console 556 544 24700 65 833 N N N On RAM Disk N N N N 122 N N N Comtrade P6 200MHz (256k cache) MS VC++ 6.0 (12.00.8804; Pent. code) Win-95; Command Window 100.0 75.2 537.4 19.1 19.2 158.5 158.0 158.0 Gnu C (gcc 2.7.2.3) Linux (2.0.32); XTerm (XFree86) 100.1 90.6 255.2 10.8 6.2 186.0 186.0 186.0 Linux (2.0.32); Console 100.0 90.5 202.4 10.6 6.6 185.9 185.9 185.9 Micron TransPort P5 233MHz (256k cache) MS VC++ 6.0 (12.00.8804; Pent. code) Win-95; Command Window 114.7 90.2 549.1 35.2 25.6 230.4 231.1 231.7 Gnu C (gcc 2.95.3-5) Cygwin Win-95; Command Window 121.2 97.6 11100 48.0 57.8 225.6 225.8 225.8 Mac 8500/120 (PPC 604, 256k cache) Metrowerks CW 9 (PPC/604 code) Mac OS; SIOUX Console 122 230 6850 108 411 N N N Compaq P5 166MHz MS VC++ 5.0 (Pent. code) Win-95; Command Window 162 128 817 55 33 N N N Mac 8100/100 (PPC 601, 256k cache) Gnu C (gcc 2.7) MkLinux DR 2.1; Console 258 2262 1380 187 23 N N N Metrowerks CW 11 (PPC/601 code) Mac OS; MSL 267 301 N N N N N N Metrowerks CW 11 (PPC/603 code) Mac OS; MSL 267 300 N N N N N N Metrowerks CW 9 (PPC/601 code) Mac OS; SIOUX Console 267 300 8700 220 293 N N N Metrowerks CW 9 (PPC/603 code) Mac OS; SIOUX Console 272 295 N N N N N N Metrowerks CW 7 (PPC code) Mac OS; SIOUX Con; Bad Yield 287 520 N N N N N N Metrowerks CW 5 (PPC code) Mac OS; SIOUX Con; Bad Yield 308 575 11650 246 N N N N ETO 22 MrC CW9 Plug-in (PPC/603) Mac OS; SIOUX Console 383 N N N N N N N Metrowerks CW 5 (68k/4i/NoFPU) Mac OS; SIOUX Con; Bad Yield 1069 6533 11910 486 N N N N Micron P5 90MHz (256k cache) Gnu C (gcc) Linux; Console 312 329 226 84 N N N N Linux; XTerm Window 313 329 1430 78 N N N N MS VC++ 2.0 (Pent. code) Win-NT; Command Window 320 281 4130 120 N N N N Macintosh (PPC 601, 80MHz) PowerPC Code (beta compiler) Mac OS 375 677 N N N N N N Mac 5300/100 (PPC 603) Metrowerks CW 7 (PPC code) Mac OS; SIOUX Con; Bad Yield 384 402 N 425 N N N N DEC Alpha NT (150MHz) CLAXP (Alpha code) Win-NT; Command Window 439 689 N N N N N N Comtrade 486DX2 66MHz (256k cache) Gnu C (gcc 2.7.2.3) Linux (2.0.32); Console 457.9 691.8 349.1 140.1 39.8 2308.9 2308.9 2308.9 DEC Alpha OSF/1 DEC C++ (Alpha code) XTerm Window 563 312 N N N N N N Sun SPARC-Station 10 Gnu C (gcc) XTerm Window 1086 526 296 64 N N N N Sun SPARC-Station IPX Sun Compiler XTerm Window 2225 1662 N N N N N N Mac IIci (68030 25MHz) Metrowerks CW 5 (68k/4i/FPU) Mac OS; SIOUX Con; Bad Yield 2863 11080 24595 1003 N N N N MPW Compiler; ANSI Library Mac OS; MPW Console 2708 10724 N N N N N N ------------------------------------------------------------------------------------------------------ N = test not run F = test failed in some way ====================================================================================================== Notes ====================================================================================================== These benchmarks test very different aspects of a machine: 'primes 1000000' mallocs lots of memory and munches on it (1000000th prime is 15485863) 'reals 500' does masses of floating-point twiddling (calls routine in inner loop) 'lines c 5000' writes many lines to the console (via buffered output; use 80x25 screen) 'lines f 20000' writes to and reads from a file (creates a 60+ Mb file) 'files 20 500' creates and destroys many files (makes and removes 10000 files) 'estpi N 1000000000' estimates value of pi using N threads (run with N = 1, 2, 4) The benchmarks should be compiled with as much optimization as your normal delivery compiler can perform. You should run the benchmark programs as normal applications in a normal environment (i.e., don't be running any other applications, but also don't strip your machine of normal device-drivers, clocks, interrupt handlers, daemons, &c.). The results are wall-clock times reported in seconds. This file is directly compilable! To do so, first select the platform by defining one of: kForWinMSC, kForMacCW, kForUnixGCC and, to select the benchmark program, define one of: kBuildPrimes, kBuildReals, kBuildLines, kBuildFiles, kBuildEstPi (see sample makefiles at end of this file). Or, if you'd rather, you can cut-and-paste parts out of this file into separate bench.h, primes.c, reals.c, lines.c, files.c and estpi.c files. ====================================================================================================== */ /* * Headers (use appropriate one) * =========================================================================== */ #ifdef kForWinMSC /* * --- bench.h -- Windows / Microsoft C -------------------------------------- */ #define kQueryArgs 0 #ifndef kDoDebug #define kDoDebug 0 #endif #define kInitialize #ifdef kHiResTime #include #define kTimeDecl DWORD dwBegTime; #define kTimeStart dwBegTime = GetTickCount (); #define kTimeReport \ { \ DWORD dwEndTime, dwDeltaTime; \ dwEndTime = GetTickCount (); \ dwDeltaTime = dwEndTime - dwBegTime; \ printf ("secs = %.1f\n", ((double)dwDeltaTime / 1000.0)); \ } #else #include #define kTimeDecl time_t ttBegSecond; #define kTimeStart ttBegSecond = time (NULL); #define kTimeReport printf ("secs = %ld\n", (long)(time (NULL) - ttBegSecond)); #endif #define kYieldCode #include #define kDirMk(nam) _mkdir (nam) #define kDirRm(nam) _rmdir (nam) #define kDirSep "\\" #define kDirCur "" #include #define kTypeThreadRet DWORD WINAPI #define kTypeThreadArg LPVOID #define kTypeThreadId HANDLE #define kThreadDecl DWORD dwDummy; #define kThreadNew(rtn, arg, pretid) \ ( \ (*(pretid)) = \ CreateThread (NULL, 0, rtn, arg, 0, &dwDummy), \ (!(*(pretid))) \ ) #define kThreadKill(id) TerminateThread (id, 0) #define kThreadWait(id) WaitForSingleObject (id, INFINITE) #endif #ifdef kForMacCW /* * --- bench.h -- Macintosh / Metrowerks CodeWarrior ------------------------- */ #define kQueryArgs 1 #ifndef kDoDebug #define kDoDebug 0 #endif #include #define kInitialize \ { \ SIOUXSettings.asktosaveonclose = false; \ SIOUXSettings.columns = 80; \ SIOUXSettings.rows = 25; \ } #ifdef kHiResTime #include #define kTimeDecl UnsignedWide uwBegTime; #define kTimeStart Microseconds (&uwBegTime); #define kTimeReport \ { \ UnsignedWide uwEndTime; \ SInt32 lUSecs; \ Microseconds (&uwEndTime); \ if (uwEndTime.hi == uwBegTime.hi) \ { \ lUSecs = uwEndTime.lo - uwBegTime.lo; \ } else { \ lUSecs = uwEndTime.lo + (0xFFFFFFFF - uwBegTime.lo); \ } \ printf ("secs = %.1f\n", (double)lUSecs / 1000000.0); \ } #else #include #define kTimeDecl time_t ttBegSecond; #define kTimeStart ttBegSecond = time (NULL); #define kTimeReport printf ("secs = %ld\n", (long)(time (NULL) - ttBegSecond)); #endif #include #include SInt32 lNextYield = LONG_MIN; #define kYieldCode \ { \ SInt32 lNow = LMGetTicks (); \ if (lNow > lNextYield) \ { \ EventRecord evt; \ WaitNextEvent (everyEvent, &evt, 0, nil); \ SIOUXHandleOneEvent (&evt); \ lNextYield = evt.when + 6; \ } \ } #include #include #include long lDummy; unsigned char acBuff[64]; #define kDirMk(nam) \ ( \ BlockMove (nam, acBuff+1, strlen (nam)), \ *acBuff = strlen (nam), \ DirCreate (0, 0, acBuff, &lDummy) \ ) #define kDirRm(nam) \ ( \ BlockMove (nam, acBuff+1, strlen (nam)), \ *acBuff = strlen (nam), \ HDelete (0, 0, acBuff) \ ) #define kDirSep ":" #define kDirCur ":" #include #include #define kTypeThreadRet OSStatus #define kTypeThreadArg void* #define kTypeThreadId MPTaskID #define kThreadDecl \ int iTasksIndex = 0; \ int bTasksDone = 0; \ MPQueueID qidCompletion; #define kThreadNew(rtn, arg, pretid) \ ( \ ((iTasksIndex == 0) && MPCreateQueue (&qidCompletion)), \ MPCreateTask \ ( \ rtn, \ arg, \ 0, \ qidCompletion, \ (void*)(iTasksIndex++), \ NULL, \ 0, \ pretid \ ) \ ) #define kThreadKill(id) MPTerminateTask (id, noErr) #define kThreadWait(id) \ if (!bTasksDone) { \ long lWaitFor; \ int* pbDone; \ OSStatus ossReason; \ void* pvIndex; \ int iIndex; \ EventRecord evt; \ lWaitFor = GetCaretTime (); \ pbDone = (int*)NewPtrClear (iThreads * sizeof(int)); \ while (!bTasksDone) \ { \ WaitNextEvent (everyEvent, &evt, lWaitFor, nil); \ SIOUXHandleOneEvent (&evt); \ ossReason = \ MPWaitOnQueue \ ( \ qidCompletion, \ &pvIndex, \ NULL, \ NULL, \ kDurationImmediate \ ); \ if (ossReason == noErr) \ { \ for (iIndex = 0; iIndex < iThreads; iIndex++) \ { \ if (iIndex == (int)pvIndex) \ { \ pbDone[iIndex] = 1; \ bTasksDone = 1; \ for (iIndex = 0; iIndex < iThreads; iIndex++) \ { \ if (!(pbDone[iIndex])) \ { \ bTasksDone = 0; \ break; \ } \ } \ break; \ } \ } \ } \ } \ DisposePtr ((Ptr)pbDone); \ } #endif #ifdef kForUnixGCC /* * --- bench.h -- Unix / Gnu C ----------------------------------------------- */ #define kQueryArgs 0 #ifndef kDoDebug #define kDoDebug 0 #endif #define kInitialize #ifdef kHiResTime #include #include #define kTimeDecl struct timeval tvBegTime; #define kTimeStart gettimeofday (&tvBegTime, NULL); #define kTimeReport \ { \ struct timeval tvEndTime; \ long lSecs, lUSecs; \ gettimeofday (&tvEndTime, NULL); \ lSecs = tvEndTime.tv_sec - tvBegTime.tv_sec; \ lUSecs = tvEndTime.tv_usec - tvBegTime.tv_usec; \ printf ("secs = %.1f\n", lSecs + ((double)lUSecs / 1000000.0)); \ } #else #include #define kTimeDecl time_t ttBegSecond; #define kTimeStart ttBegSecond = time (NULL); #define kTimeReport printf ("secs = %ld\n", (long)(time (NULL) - ttBegSecond)); #endif #define kYieldCode #include #include #define kDirMk(nam) mkdir (nam, 0777) #define kDirRm(nam) rmdir (nam) #define kDirSep "/" #define kDirCur "" #include #include #define kTypeThreadRet void* #define kTypeThreadArg void* #define kTypeThreadId pthread_t #define kThreadDecl #define kThreadNew(rtn, arg, pretid) \ ( \ pthread_create (pretid, NULL, rtn, arg) \ ) #define kThreadKill(id) pthread_kill (id, SIGINT) #define kThreadWait(id) pthread_join (id, NULL) #endif /* * --------------------------------------------------------------------------- */ /* * Source Code * =========================================================================== */ #ifdef kBuildPrimes /* * --- primes.c -------------------------------------------------------------- * * Computes the first primes using a Sieve of Eratosthenes. * To keep things integral, uses a running integer square-root * algorithm to determine when to stop searching through the sieve. */ #if !defined (kForWinMSC) && !defined (kForMacCW) && !defined (kForUnixGCC) #include "bench.h" #endif #include #include #include int main ( int argc, char* argv[] ) { kTimeDecl int iNumArgs; long* plPrimes; long lNumCalc; long lCount; long lNumber; long lTest; long lEnd; long lInc = -1; long lSum = 0; kInitialize #if kQueryArgs printf ("num > "); iNumArgs = scanf ("%ld", &lNumCalc); #else if (argc != 2) { printf ("primes \n"); exit (1); } iNumArgs = sscanf (argv[1], "%ld", &lNumCalc); #endif if (iNumArgs != 1) { printf ("not a number\n"); exit (1); } kTimeStart if (lNumCalc < 4) { lNumCalc = 4; } lEnd = -1; for (; lSum <= 5; lInc += 2, lSum += lInc, lEnd++) ; plPrimes = (long*)(malloc (sizeof(long) * lNumCalc)); if (!plPrimes) { printf ("can't malloc\n"); exit (1); } plPrimes[0] = 2; plPrimes[1] = 3; for (lNumber = 5, lCount = 2; lCount < lNumCalc; lNumber += 2) { if (lSum <= lNumber) { lInc += 2; lSum += lInc; lEnd++; } for (lTest = 0; ; lTest++) { if (plPrimes[lTest] > lEnd) { plPrimes[lCount++] = lNumber; break; } if ((lNumber % plPrimes[lTest]) == 0) { break; } } kYieldCode } #if kDoDebug for (lCount = 0; lCount < lNumCalc; lCount++) { if ((lCount % 10) == 0) { printf ("\n"); } printf ("%ld ", plPrimes[lCount]); } printf ("\n\n"); #else printf ("%ld : %ld\n", lNumCalc, plPrimes[lNumCalc-1]); #endif free (plPrimes); kTimeReport return 0; } #endif #ifdef kBuildReals /* * --- reals.c --------------------------------------------------------------- * * Simply applies the Quadratic Formula to lots of quadratic equations. * Calls a function (midpoint) on the roots, just to make things interesting. */ #if !defined (kForWinMSC) && !defined (kForMacCW) && !defined (kForUnixGCC) #include "bench.h" #endif #include #include #include double midpoint ( double r1, double r2 ) { double mp; mp = (r1 + r2) / 2.0; return mp; } int main ( int argc, char* argv[] ) { kTimeDecl int iNumArgs; int i; int j; int k; int maxval; double a; double b; double c; double disc; double tmp1; double tmp2; double r1; double r2; double mp; double sum; kInitialize #if kQueryArgs printf ("num > "); iNumArgs = scanf ("%d", &maxval); #else if (argc != 2) { printf ("reals \n"); exit (1); } iNumArgs = sscanf (argv[1], "%d", &maxval); #endif if (iNumArgs != 1) { printf ("not a number\n"); exit (1); } sum = 0.0; kTimeStart for (i = 1; i < maxval; i++) { a = i; for (j = 0; j < maxval; j++) { b = j; for (k = 0; k < maxval; k++) { c = k; disc = (b * b) - (4.0 * a * c); tmp1 = sqrt (fabs (disc)); tmp2 = 2.0 * a; r1 = (-b - tmp1) / tmp2; r2 = (-b + tmp1) / tmp2; mp = midpoint (r1, r2); sum += mp; #if kDoDebug printf ( "%4d %4d %4d %9.3f %9.3f %9.3f\n", i, j, k, r1, r2, mp ); #endif } } kYieldCode } kTimeReport printf ("sum = %g\n", sum); return 0; } #endif #ifdef kBuildLines /* * --- lines.c --------------------------------------------------------------- * * Uses standard, buffered I/O to write lots of lines to a file or stdout. * If to a file, reads the file to verify the write was done correctly. */ #if !defined (kForWinMSC) && !defined (kForMacCW) && !defined (kForUnixGCC) #include "bench.h" #endif #include #include #define kLineLength 83 char acLine[kLineLength]; int main ( int argc, char* argv[] ) { kTimeDecl int iNumArgs; char cType; int iLimit; int iCount; int iIndex; FILE* pfTst; kInitialize #if kQueryArgs printf ("f/c > "); gets (acLine); cType = acLine[0]; printf ("num > "); iNumArgs = scanf ("%d", &iLimit); #else if (argc != 3) { printf ("lines \n"); exit (1); } cType = *(argv[1]); iNumArgs = sscanf (argv[2], "%d", &iLimit); #endif if (iNumArgs != 1) { printf ("not a number\n"); exit (1); } kTimeStart if (cType == 'f') { pfTst = fopen ("lines.dat", "w"); if (!pfTst) { printf ("can't open file for writing\n"); exit (1); } for (iCount = 0; iCount < iLimit; iCount++) { for (iIndex = 0; iIndex < (kLineLength - 4); iIndex++) { acLine[iIndex+0] = '*'; acLine[iIndex+1] = '\n'; acLine[iIndex+2] = '\0'; fputs (acLine, pfTst); } kYieldCode } fclose (pfTst); pfTst = fopen ("lines.dat", "r"); if (!pfTst) { printf ("can't open file for reading\n"); exit (1); } for (iCount = 0; iCount < iLimit; iCount++) { for (iIndex = 0; iIndex < (kLineLength - 4); iIndex++) { fgets (acLine, kLineLength, pfTst); if (acLine[iIndex+1] != '\n') { printf ("error in file's contents\n"); exit (1); } } } fclose (pfTst); } if (cType == 'c') { for (iCount = 0; iCount < iLimit; iCount++) { for (iIndex = 0; iIndex < (kLineLength - 4); iIndex++) { acLine[iIndex+0] = '*'; acLine[iIndex+1] = '\n'; acLine[iIndex+2] = '\0'; fputs (acLine, stdout); } kYieldCode } } kTimeReport return 0; } #endif #ifdef kBuildFiles /* * --- files.c --------------------------------------------------------------- * * This just creates a big tree of directories and little files. * It then removes them all. */ #if !defined (kForWinMSC) && !defined (kForMacCW) && !defined (kForUnixGCC) #include "bench.h" #endif #include #include int main ( int argc, char* argv[] ) { kTimeDecl int iNumArgs; long lNumDirs; long lNumFils; long lDir; long lFil; long lCount; FILE* pfTst; char acName[32]; kInitialize iNumArgs = 0; #if kQueryArgs printf ("dirs > "); iNumArgs += scanf ("%ld", &lNumDirs); printf ("files > "); iNumArgs += scanf ("%ld", &lNumFils); #else if (argc != 3) { printf ("files \n"); exit (1); } iNumArgs += sscanf (argv[1], "%ld", &lNumDirs); iNumArgs += sscanf (argv[2], "%ld", &lNumFils); #endif if (iNumArgs != 2) { printf ("not a number\n"); exit (1); } kTimeStart lCount = 0; for (lDir = 0; lDir < lNumDirs; lDir++) { sprintf (acName, "DIR%04ld", lDir); if (kDirMk (acName)) { printf ("could not create directory <%s>\n", acName); exit (2); } for (lFil = 0; lFil < lNumFils; lFil++) { sprintf (acName, kDirCur "DIR%04ld" kDirSep "FIL%04ld", lDir, lFil); pfTst = fopen (acName, "w"); fclose (pfTst); kYieldCode } } #if !kDoDebug for (lDir = 0; lDir < lNumDirs; lDir++) { for (lFil = 0; lFil < lNumFils; lFil++) { sprintf (acName, kDirCur "DIR%04ld" kDirSep "FIL%04ld", lDir, lFil); remove (acName); kYieldCode } sprintf (acName, "DIR%04ld", lDir); kDirRm (acName); } #endif kTimeReport return 0; } #endif #ifdef kBuildEstPi /* * --- estpi.c --------------------------------------------------------------- * * This estimates the value of PI by integrating the area under 4/(1+x^2) * from 0 to 1, by summing areas of rectangles. The work of computing the * areas of these rectangles is divided amongst a given number of threads. */ #if !defined (kForWinMSC) && !defined (kForMacCW) && !defined (kForUnixGCC) #include "bench.h" #endif #include #include typedef struct { int iThreads; int iOffset; int iIntervals; double dPartial; kTypeThreadId tiId; } tEstPiThread; kTypeThreadRet EstPiPart ( kTypeThreadArg taArg ) { tEstPiThread* teptData; register int iThreads; register int iIntervals; register double dWidth; register double dLocX; register double dSum; register int iIndex; teptData = (tEstPiThread*)taArg; iThreads = teptData->iThreads; iIntervals = teptData->iIntervals; dWidth = 1.0 / iIntervals; dSum = 0.0; for (iIndex = teptData->iOffset; iIndex < iIntervals; iIndex += iThreads) { dLocX = (iIndex + 0.5) * dWidth; dSum += 4.0 / (1.0 + (dLocX * dLocX)); #if kDoDebug printf ( "thread %d index=%d loc=%f sum=%f\n", teptData->iOffset, iIndex, dLocX, dSum ); #endif } dSum *= dWidth; teptData->dPartial = dSum; return 0; } int main ( int argc, char* argv[] ) { kTimeDecl kThreadDecl int iNumArgs; int iThreads; int iIntervals; int iIndex; int bError; tEstPiThread* teptData; double dMyPi; double dTruePi = 3.141592653589793238462643383279502884197169399; kInitialize iNumArgs = 0; #if kQueryArgs printf ("threads > "); iNumArgs += scanf ("%d", &iThreads); printf ("intervals > "); iNumArgs += scanf ("%d", &iIntervals); #else if (argc != 3) { printf ("estpi \n"); exit (1); } iNumArgs += sscanf (argv[1], "%d", &iThreads); iNumArgs += sscanf (argv[2], "%d", &iIntervals); #endif if (iNumArgs != 2) { printf ("not a number\n"); exit (1); } kTimeStart if (iThreads <= 0) { teptData = (tEstPiThread*)(malloc (sizeof(tEstPiThread))); if (!teptData) { printf ("can't malloc\n"); exit (1); } teptData->iThreads = 1; teptData->iOffset = 0; teptData->iIntervals = iIntervals; EstPiPart (teptData); dMyPi = teptData->dPartial; free (teptData); } else { teptData = (tEstPiThread*)(malloc (sizeof(tEstPiThread) * iThreads)); if (!teptData) { printf ("can't malloc\n"); exit (1); } for (iIndex = 0; iIndex < iThreads; iIndex++) { teptData[iIndex].iThreads = iThreads; teptData[iIndex].iOffset = iIndex; teptData[iIndex].iIntervals = iIntervals; bError = kThreadNew ( EstPiPart, &(teptData[iIndex]), &(teptData[iIndex].tiId) ); if (bError) { for (iIndex--; iIndex >= 0; iIndex--) { kThreadKill (teptData[iIndex].tiId); } free (teptData); printf ("couldn't start thread\n"); exit (1); } } dMyPi = 0.0; for (iIndex = 0; iIndex < iThreads; iIndex++) { kThreadWait (teptData[iIndex].tiId); dMyPi += teptData[iIndex].dPartial; #if kDoDebug printf ( "thread %d part = % .16f\n", iIndex, teptData[iIndex].dPartial ); #endif } free (teptData); } printf ( "estimation of value of pi: % .16f\n" " approximate value of pi: % .16f\n" " difference in values: % .16f\n", dMyPi, dTruePi, dMyPi - dTruePi ); kTimeReport return 0; } #endif /* * --------------------------------------------------------------------------- * * =========================================================================== */ /* Sample Makefiles ============================================================================== # --- Makefile.msc ----------------------------------------------------------- # # Makefile for nmake and msc on Windows. # CC=cl CFLAGS=-DkForWinMSC -DkHiResTime -nologo -W3 COPTI=-Og -Oi -Ot -Oy -Ob2 -Gs -Gf -G6 COPTF=$(COPTI) all : primes reals lines files estpi run : all lines c 5000 primes 1000000 reals 500 lines f 20000 files 20 500 estpi 1 1000000000 estpi 2 1000000000 estpi 4 1000000000 primes : primes.exe reals : reals.exe lines : lines.exe files : files.exe estpi : estpi.exe primes.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildPrimes -Fe$@ bench.c reals.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTF) -DkBuildReals -Fe$@ bench.c lines.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildLines -Fe$@ bench.c files.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildFiles -Fe$@ bench.c estpi.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTF) -DkBuildEstPi -Fe$@ bench.c bench.h : echo. >$@ clean : if exist bench.h del bench.h if exist *.obj del *.obj if exist *.exe del *.exe if exist lines.dat del lines.dat # --- Makefile.AMDx64 -------------------------------------------------------- # # Makefile for nmake and msc/AMDx64 on Windows. # CC=cl CFLAGS=-DkForWinMSC -DkHiResTime -nologo -W3 COPTI=-favor:AMD64 -fp:fast -O2 -Gs -Ob2 -Og -Oi COPTF=$(COPTI) all : primes reals lines files estpi run : all lines c 5000 primes 1000000 reals 500 lines f 20000 files 20 500 estpi 1 1000000000 estpi 2 1000000000 estpi 4 1000000000 primes : primes.exe reals : reals.exe lines : lines.exe files : files.exe estpi : estpi.exe primes.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildPrimes -Fe$@ bench.c reals.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTF) -DkBuildReals -Fe$@ bench.c lines.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildLines -Fe$@ bench.c files.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildFiles -Fe$@ bench.c estpi.exe : bench.c bench.h $(CC) $(CFLAGS) $(COPTF) -DkBuildEstPi -Fe$@ bench.c bench.h : echo. >$@ clean : if exist bench.h del bench.h if exist *.obj del *.obj if exist *.exe del *.exe if exist lines.dat del lines.dat # --- Makefile.gcc ----------------------------------------------------------- # # Makefile for gmake and gcc on Unix. # CC=gcc CFLAGS=-DkForUnixGCC -DkHiResTime -static -Wall -mcpu=i686 COPTI=-O3 -fthread-jumps -fcaller-saves -fomit-frame-pointer -funroll-loops COPTF=$(COPTI) -ffast-math -funroll-all-loops PTLIB=-lpthread all : primes reals lines files estpi run : all ./lines c 5000 ./primes 1000000 ./reals 500 ./lines f 20000 ./files 20 500 ./estpi 1 1000000000 ./estpi 2 1000000000 ./estpi 4 1000000000 primes : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildPrimes -o $@ bench.c reals : bench.c bench.h $(CC) $(CFLAGS) $(COPTF) -DkBuildReals -o $@ bench.c lines : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildLines -o $@ bench.c files : bench.c bench.h $(CC) $(CFLAGS) $(COPTI) -DkBuildFiles -o $@ bench.c estpi : bench.c bench.h $(CC) $(CFLAGS) $(COPTF) -DkBuildEstPi -D_REENTRANT -o $@ bench.c $(PTLIB) bench.h : touch $@ clean : rm -f bench.h primes reals lines files estpi lines.dat # ---------------------------------------------------------------------------- ============================================================================== */