' ' Document: Whetsvb.txt ' File Group: Classic Benchmarks ' Creation Date: 9 December 1996 ' Revision Date: 11 January 1997 ' ' Title: Whetstone Benchmark in Visual Basic ' Keywords: WHETSTONE BENCHMARK PERFORMANCE MIPS ' MWIPS MFLOPS ' ' Abstract: Visual Basic version of Whetstone one of ' the Classic Numeric Benchmarks with example ' results for PCs. ' ' Contributor: Roy Longbottom 101323.2241@compuserve.com ' or Roy_Longbottom@compuserve.com ' '************************************************************* DefLng I, N DefInt H, J-L DefSng A-G, O-Z Dim e(4) Dim results(8) Dim time_loop(8) Dim heading$(8) Dim ops(8) Dim flops(8) Sub Command1_Click () '*********************************************************** ' Visual Basic Whetstone benchmark Single 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 ' PC versions Roy Longbottom 1996 ' '*********************************************************** ' Operating Instructions whetsvb.txt ' ' 1. Load Visual Basic ' 2. Click File, New Project ' 3. Click View Code button (Form 1) ' 4. VB3 Click File, Load Text, select whetsvb.txt, Replace ' VB4 Click Insert, File, select whetsvb.txt, Open ' 5. Click View Form Button ' 6. Click Command button in Toolbox (under ab), move pointer to ' bottom right hand corner of Form, size button (6 x 4 dots) ' 7. VB3 Click Window, Properties ' VB4 Right Click on Command button, Properties ' 8. Change Caption from "Command1" to "Run" ' 9. Click on blank form for Form1 Properties ' 10. Change Caption from "Form1" to "Whetstone Benchmark" ' Change Name from "Form1" to "Whets" ' Change BackColor to White VB3 via ... at top ' 11. Create a second button left of "Run", Caption "Exit" ' 12. On Form Click VB3 Window, Menu Design ' VB4 Tools, Menu Editor ' 13. Enter the following data: ' Caption "&File", Name "MenuFile", Click Next and > arrow ' "&Exit" "MenuFileExit" Next and < arrow ' "&Help" "HelpMenu" OK ' Menu Design/Editor window should have: ' &File ' ----&Exit ' &Help ' Form should have menu bar with File and Help ' 14. File, Save Project As, Yes to Save Changes to Whets? or ' Whets.frm?, Save or OK ' Save Project As change name to ' VB3 "whets.mak" OK ' VB4 "whets.vbp" Save ' 15. Click Run, Start, then "Run" button on form ' 16. When benchmark has finished enter running details ' in the Input Boxes. Click "Exit" button on form ' 17. If all data was not displayed, resize the form and move ' buttons with mouse (changes Form Properties). File, Save ' 18. Click File, Make EXE File, Name "Whets.exe" ' ' Whets.exe can then be run via Windows and will probably ' be slightly faster than via Visual Basic. Results are ' appended to file Whets.txt which can be loaded into a ' Word Processor or Spreadsheet. ' ' The .exe file from VB3 can be copied to other PCs for ' running via Windows. The .exe from VB4 needs various ' DLLs to run elsewhere (VB40032.DLL, OLEPRO32.DLL, ' MSVCRT40.DLL) or the Setup toolkit can be used to ' generate a distributable Windows application. ' ' See end of this listing for Exit and Help procedures ' '*********************************************************** ' ' The program should run for about 100 seconds on PCs ' (adjustable - variable duration). This time is ' necessary because of the poor clock resolution. ' '*********************************************************** ' ' The original benchmark had a single variable I which ' controlled the running time. Constants with values up ' to 899 were multiplied by I to control the number ' passes for each loop. It was found that large values ' of I could overflow index registers so an extra outer ' loop with a second variable J was added. ' ' Self timing versions were produced during the early ' days. The 1978 changes supplied timings of individual ' loops and these were used later to produce MFLOPS and ' MOPS ratings. ' ' 1987 changes converted the benchmark to Fortran 77 ' standards and removed redundant IF statements and ' loops to leave the 8 active loops N1 to N8. Procedure ' P3 was changed to use global variables to avoid over- ' optimisation with the first two statements changed from ' X1=X and Y1=Y to X=Y and Y=Z. A self time calibrating ' version for PCs was also produced, the facility being ' incorporated in this version. ' ' This version has changes to avoid worse than expected ' speed ratings, due to underflow, and facilities to show ' that consistent numeric output is produced with varying ' optimisation levels or versions in different languages. ' ' Some of the procedures produce ever decreasing numbers. ' To avoid problems, variables T and T1 have been changed ' from 0.499975 and 0.50025 to 0.49999975 and 0.50000025. ' ' Each section now has its own double loop. Inner loops ' are run 100 times the loop constants. Calibration ' determines the number of outer loop passes. The ' numeric results produced in the main output are for ' one pass on the outer loop. As underflow problems were ' still likely on a processor 100 times faster than a 100 ' MHz Pentium, three sections have T=1.0-T inserted in the ' outer loop to avoid the problem. The two loops avoid ' index register overflows. ' ' The first section is run ten times longer than required ' for accuracy in calculating MFLOPS. This time is divided ' by ten for inclusion in the MWIPS calculations. ' ' This version has facilities for typing in details of the ' particular run. This information is appended to file ' Whets.txt along with the results. ' ' Roy Longbottom 101323.2241@compuserve.com ' '*********************************************************** ' ' Whetstone benchmark results are available in whets.tbl ' from ftp.nosc.mil/pub/aburto. The results include ' further details of the benchmarks. ' '*********************************************************** ' ' Source code is available in C++, C, Fortran, Basic and ' Visual Basic in the same format as this version. Pre- ' compiled versions for PCs are also available via C++. ' These comprise optimised and non-optimised versions ' for DOS, Windows and NT. ' '*********************************************************** ' ' Examples of Results ' ' Single Precision Whetstone Benchmark Visual Basic 3 ' ' Month run .. 04/1996 ' PC model .. Escom ' CPU .. Pentium ' Clock MHz .. 100 ' Cache .. 256K ' Options .. Neptune chipset ' OS/DOS .. Windows 95 ' Compiler .. Visual Basic ' Version .. 3.0 ' Run by .. Roy Longbottom ' From .. UK ' Mail .. 101323.2241@compuserve.com ' ' Loop content Result MFLOPS MOPS Seconds ' ' N1 floating point -1.12475000000000000 0.712 1.214 ' N2 floating point -1.12274800000000000 0.692 8.742 ' N3 if then else 1.00000000000000000 0.642 7.250 ' N4 fixed point 12.00000000000000000 1.118 12.680 ' N5 sin,cos etc. 0.49904630000000000 0.934 4.008 ' N6 floating point 0.99999990000000000 0.649 37.410 ' N7 assignments 3.00000000000000000 0.328 25.371 ' N8 exp,sqrt etc. 0.75110860000000000 0.499 3.352 ' ' MWIPS 4.499 100.027 ' ' Single Precision Whetstone Benchmark Visual Basic 4 ' ' Month run .. 04/1996 ' PC model .. Escom ' CPU .. Pentium ' Clock MHz .. 100 ' Cache .. 256K ' Options .. Neptune chipset ' OS/DOS .. Windows 95 ' Compiler .. Visual Basic ' Version .. 4.0 ' Run by .. Roy Longbottom ' From .. UK ' Mail .. 101323.2241@compuserve.com ' ' Loop content Result MFLOPS MOPS Seconds ' ' N1 floating point -1.12475000000000000 1.146 1.323 ' N2 floating point -1.12274800000000000 1.085 9.782 ' N3 if then else 1.00000000000000000 0.968 8.450 ' N4 fixed point 12.00000000000000000 1.696 14.671 ' N5 sin,cos etc. 0.49904630000000000 1.107 5.938 ' N6 floating point 0.99999990000000000 1.515 28.121 ' N7 assignments 3.00000000000000000 0.586 24.930 ' N8 exp,sqrt etc. 0.75110860000000000 0.449 6.540 ' ' MWIPS 7.919 99.755 ' ' '*********************************************************************** ' ' Example results compiled versions ' ' ' Visual Basic 3.0 ' ' MWIPS MFLOPS MFLOPS MFLOPS COS EXP FIXPT IF EQUAL ' Key 1 2 3 MOPS MOPS MOPS MOPS MOPS ' ' P3 0.665 0.096 0.094 0.093 0.154 0.080 0.191 0.105 0.047 ' P4 1.82 0.300 0.290 0.262 0.297 0.174 0.469 0.263 0.137 ' P5 4.50 0.712 0.692 0.649 0.934 0.499 1.12 0.642 0.328 ' P6 11.6 1.36 1.32 2.50 1.52 0.914 2.84 1.29 0.768 ' ' ' Visual Basic 4.0 ' ' MWIPS MFLOPS MFLOPS MFLOPS COS EXP FIXPT IF EQUAL ' Key 1 2 3 MOPS MOPS MOPS MOPS MOPS ' ' P3 1.03 0.122 0.122 0.190 0.132 0.052 0.259 0.135 0.080 ' P4 3.42 0.499 0.478 0.674 0.329 0.141 0.837 0.468 0.268 ' P5 7.92 1.15 1.09 1.52 1.11 0.449 1.70 0.968 0.586 ' P6 16.8 2.83 2.54 3.59 2.27 0.933 2.71 1.95 1.31 ' ' ' Systems ' ' Key System CPU MHz Cache Options OS ' ' P3 Clone AM80386DX 40 128K with 387 Windows 95 ' P4 Escom, 80486DX2 66.7 128K CIS chipset Windows 95 ' P5 Escom, Pentium 100 256K Neptune chipset Windows 95 ' P6 Dell Pro PentPro 200 256K 440FX PCIset NT 3.51 ' '************************************************************************* On Error GoTo Errline Open "Whets.txt" For Append As #1 Cls icount = 10 calibrate = 1 ixtra = 1 ix100 = 100 duration = 100 Print "Calibrating Whetstone Benchmark" Print "12345678 modules" Do ' calculate loops per second TimeUsed = 0 GoSub Whetstones Print Print TimeUsed; " seconds "; ixtra; " Passes (x 100)" calibrate = calibrate + 1 icount = icount - 1 If TimeUsed > 2 Then icount = 0 Else ixtra = ixtra * 5 End If Loop While icount > 0 If TimeUsed > 0 Then ixtra = duration * CSng(ixtra) / TimeUsed End If If ixtra < 1 Then ixtra = 1 Cls Print "Whetstone Benchmark for "; duration; " seconds duration" Print Print ixtra; " passes used (x 100)" Print calibrate = 0 Print "Visual Basic Whetstone Benchmark - Single Precision" Print Print "Loop content Result"; Print Tab(48); " MFLOPS MOPS Seconds" Print Check = 0# TimeUsed = 0 GoSub Whetstones If TimeUsed > 0 Then wips = CSng(ixtra * ix100) / (10 * TimeUsed) Else wips = 0 End If Print Print "MWIPS"; Tab(50); If wips < 100 Then Print " "; If wips < 10 Then Print " "; Print Format(wips, "####0.000"); Print Tab(70); If TimeUsed < 100 Then Print " "; If TimeUsed < 10 Then Print " "; Print Format(TimeUsed, "###0.000") Print If Check = 0 Then Print "Wrong answer": Print Print "Enter datails in the boxes for filing with the results" Print #1, "----------------- ----------------------------- "; Print #1, "--------- --------- --------- --------- --------- "; Print #1, "--------- --------- --------- ---------" Print #1, "Single Precision Whetstone Benchmark Visual "; Print #1, "Basic" Print #1, " " title$ = " Benchmark run details" Print #1, "Month run .. "; Left$(Date$, 2); "/"; Right$(Date$, 4) a$ = InputBox$("Enter PC Supplier/model", title$) Print #1, "PC model .. "; a$ a$ = InputBox$("Enter CPU chip type", title$) Print #1, "CPU .. "; a$ a$ = InputBox$("Enter clock MHz", title$) Print #1, "Clock MHz .. "; a$ a$ = InputBox$("Enter cache size", title$) Print #1, "Cache .. "; a$ a$ = InputBox$("Enter chipset/options", title$) Print #1, "Options .. "; a$ a$ = InputBox$("Enter OS/DOS used", title$) Print #1, "OS/DOS .. "; a$ Print #1, "Compiler .. "; "Visual Basic" a$ = InputBox$("Enter Visual Basic Version", title$) Print #1, "Version .. "; a$ ' Print #1, "Version .. "; "3.0" a$ = InputBox$("Enter your name", title$) Print #1, "Run by .. "; a$ a$ = InputBox$("Where are you from ?", title$) Print #1, "From .. "; a$ a$ = InputBox$("Enter E-mail address", title$) Print #1, "Mail .. "; a$ Print #1, " " Print #1, "Loop content Result "; Print #1, " MFLOPS MOPS Seconds" Print #1, " " For section = 1 To 8 Print #1, heading$(section); Tab(23); If Abs(results(section)) < 10 Then Print #1, " "; If results(section) < 0 Then Print #1, "-"; Else Print #1, " "; End If Print #1, Format(Abs(results(section)), "0.00000000000000000"); If ops(section) = 999999 Then Print #1, Tab(51); If flops(section) < 100 Then Print #1, " "; If flops(section) < 10 Then Print #1, " "; Print #1, Format(flops(section), "####0.000"); " "; Else Print #1, Tab(61); If ops(section) < 100 Then Print #1, " "; If ops(section) < 10 Then Print #1, " "; Print #1, Format(ops(section), "####0.000"); " "; End If Print #1, Tab(71); If time_loop(section) < 100 Then Print #1, " "; If time_loop(section) < 10 Then Print #1, " "; Print #1, Format(time_loop(section), "##0.000") Next section Print #1, " " Print #1, "MWIPS"; Tab(51); If wips < 100 Then Print #1, " "; If wips < 10 Then Print #1, " "; Print #1, Format(wips, "####0.000"); Print #1, Tab(71); If TimeUsed < 100 Then Print #1, " "; If TimeUsed < 10 Then Print #1, " "; Print #1, Format(TimeUsed, "###0.000") Print #1, " " Print #1, "Results to load to spreadsheet "; Print #1, " MWIPS Mflops1 Mflops2 Mflops3 Cosmops "; Print #1, " Expmops Fixpmops Ifmops Eqmops" Print #1, "Results to load to spreadsheet "; Pspeed = wips: GoSub PrintSpeed Pspeed = flops(1): GoSub PrintSpeed Pspeed = flops(2): GoSub PrintSpeed Pspeed = flops(6): GoSub PrintSpeed Pspeed = ops(5): GoSub PrintSpeed Pspeed = ops(8): GoSub PrintSpeed Pspeed = ops(4): GoSub PrintSpeed Pspeed = ops(3): GoSub PrintSpeed Pspeed = ops(7): GoSub PrintSpeed Print #1, " " Print #1, " " Close #1 Print "Results are in file Whets.txt" Exit Sub Errline: Print "Error unable to open file?" Exit Sub PrintSpeed: Print #1, " "; If Pspeed < 100 Then Print #1, " "; If Pspeed < 10 Then Print #1, " "; Print #1, Format(Pspeed, "####0.000"); " "; Return Whetstones: ' INITIALISE CONSTANTS t = .49999975 t0 = t t1 = .50000025 t2 = 2# N1 = 12 * ix100 N2 = 14 * ix100 N3 = 345 * ix100 N4 = 210 * ix100 N5 = 32 * ix100 N6 = 899 * ix100 N7 = 616 * ix100 N8 = 93 * ix100 n1mult = 10 ' MODULE 1 - ARRAY ELEMENTS stime = Timer e(1) = 1 e(2) = -1 e(3) = -1 e(4) = -1 For ix = 1 To ixtra For i = 1 To N1 * n1mult e(1) = (e(1) + e(2) + e(3) - e(4)) * t e(2) = (e(1) + e(2) - e(3) + e(4)) * t e(3) = (e(1) - e(2) + e(3) + e(4)) * t e(4) = (-e(1) + e(2) + e(3) + e(4)) * t Next i t = 1# - t Next ix t = t0 checsum = e(4) rtime = (Timer - stime) / n1mult smflops = N1 * 16 title$ = "N1 floating point" atype = 1 section = 1 GoSub Pout ' N1 * 16 floating point calculations ' MODULE 2 - ARRAY AS PARAMETER, CODED WITHOUT PARAMETERS stime = Timer For ix = 1 To ixtra For i = 1 To N2 GoSub PA Next i t = 1# - t Next ix t = t0 checsum = e(4) rtime = Timer - stime smflops = N2 * 96 title$ = "N2 floating point" atype = 1 section = 2 GoSub Pout ' N2 * 96 floating point calculations ' MODULE 3 - CONDITIONAL JUMPS stime = Timer j = 1 For ix = 1 To ixtra For i = 1 To N3 If j <> 1 Then j = 3 Else j = 2 End If If j <= 2 Then j = 1 Else j = 0 End If If j >= 1 Then j = 0 Else j = 1 End If Next i Next ix checsum = j rtime = Timer - stime smflops = N3 * 3 title$ = "N3 if then else" atype = 2 section = 3 GoSub Pout ' N3 * 3 IF THEN ELSE ' MODULE 4 - INTEGER ARITHMETIC stime = Timer j = 1 K = 2 l = 3 For ix = 1 To ixtra For i = 1 To N4 j = j * (K - j) * (l - K) K = l * K - (l - j) * K l = (l - K) * (K + j) e(l - 1) = j + K + l e(K - 1) = j * K * l Next i Next ix checsum = e(2) + e(1) rtime = Timer - stime smflops = N4 * 15 title$ = "N4 fixed point" atype = 2 section = 4 GoSub Pout ' N4 * 15 fixed point operations ' MODULE 5 - TRIG. FUNCTIONS stime = Timer x = .5 Y = .5 For ix = 1 To ixtra For i = 1 To N5 x = t * Atn(t2 * Sin(x) * Cos(x) / (Cos(x + Y) + Cos(x - Y) - 1)) Y = t * Atn(t2 * Sin(Y) * Cos(Y) / (Cos(x + Y) + Cos(x - Y) - 1)) Next i t = 1# - t Next ix t = t0 checsum = Y rtime = Timer - stime smflops = N5 * 26 title$ = "N5 sin,cos etc." atype = 2 section = 5 GoSub Pout ' N5 * 26 function calls and floating point operations ' MODULE 6 - PROCEDURE CALLS stime = Timer x = 1# Y = 1# Z = 1# For ix = 1 To ixtra For i = 1 To N6 GoSub P3 Next i Next ix checsum = Z rtime = Timer - stime smflops = N6 * 6 title$ = "N6 floating point" atype = 1 section = 6 GoSub Pout ' N6 * 6 floating point operations ' MODULE 7 - ARRAY REFERENCES stime = Timer j = 1 K = 2 l = 3 e(1) = 1 e(2) = 2 e(3) = 3 For ix = 1 To ixtra For i = 1 To N7 GoSub PO Next i Next ix checsum = e(3) rtime = Timer - stime smflops = N7 * 3 title$ = "N7 assignments" atype = 2 section = 7 GoSub Pout ' N7 * 3 assignments ' MODULE 8 - STANDARD FUNCTIONS stime = Timer x = .75 For ix = 1 To ixtra For i = 1 To N8 x = Sqr(Exp(Log(x) / t1)) Next i Next ix checsum = x rtime = Timer - stime smflops = N8 * 4 title$ = "N8 exp,sqrt etc." atype = 2 section = 8 GoSub Pout ' N8 * 4 function calls and floating point operations Return ' END OF MAIN ROUTINE PA: ' PROCEDURE PA j = 0 Do e(1) = (e(1) + e(2) + e(3) - e(4)) * t e(2) = (e(1) + e(2) - e(3) + e(4)) * t e(3) = (e(1) - e(2) + e(3) + e(4)) * t e(4) = (-e(1) + e(2) + e(3) + e(4)) / t2 j = j + 1 Loop While j < 6 Return PO: ' PROCEDURE P0 e(j) = e(K) e(K) = e(l) e(l) = e(j) Return P3: ' PROCEDURE P3 x = Y Y = Z x = t * (x + Y) Y = t1 * (x + Y) Z = (x + Y) / t2 Return Pout: Check = Check + checsum time_loop(section) = rtime heading$(section) = title$ TimeUsed = TimeUsed + rtime If rtime <= 0! Then smflops = 0! Else smflops = CSng(ixtra) * smflops / (rtime * 1000000!) End If If calibrate = 1 Then results(section) = checsum Print "#"; End If If calibrate = 0 Then Print heading$(section); Tab(20); If Abs(results(section)) < 10 Then Print " "; If results(section) < 0 Then Print "-"; Else Print " "; End If Print Format(Abs(results(section)), "0.00000000000000000"); If atype = 1 Then flops(section) = smflops ops(section) = 999999 Print Tab(50); If flops(section) < 100 Then Print " "; If flops(section) < 10 Then Print " "; Print Format(flops(section), "####0.000"); " "; Else flops(section) = 0 ops(section) = smflops Print Tab(60); If ops(section) < 100 Then Print " "; If ops(section) < 10 Then Print " "; Print Format(ops(section), "####0.000"); " "; End If Print Tab(70); If time_loop(section) < 100 Then Print " "; If time_loop(section) < 10 Then Print " "; Print Format(time_loop(section), "##0.000"); " " End If Return End Sub Sub Command2_Click () Unload Whets End End Sub Sub HelpMenu_Click () MsgBox "Whetstone Benchmark Visual Basic Version" + Chr$(13) + " By Roy Longbottom December 1996" End Sub Sub MenuFileExit_Click () Unload Whets End End Sub