sch (03/08/83)
echo x - Readme cat >Readme <<'!E!O!F!' The program buchholz is a performance measuring tool from "A synthetic job for measuring system performance" by W. Buchholz, IBM Syst. Journal, No. 4 1969 page 309. It is a useful tool since it combines both I/O and computational speed tests. Two bencmarks are combined together here, the first is a compute bound matrix problem and the second is a file update problem. The input stream consists of lines with three numbers. First the number of master file records, second the number of transaction file records, and third the number of computational cycles. If the first two are zero then the test does no I/O, if the number of computational steps is zero then it does no computation. See the file 'Sample' for a typical set of input values. The output stream contains the results of these tests, formatted for readablity. Results are included for: Filename Machine Running Unix Version -------------------------------------------------------- Vax750 Vax 11/750 4.1bsd Vax780 Vax 11/780 4.1bsd PWB11-70 Pdp 11/70 PWB Unix See the source if you want to change either, 1) the type of I/O used (now stdio), 2) or the type of numbers used in the computation test. !E!O!F! echo x - buchholz.c cat >buchholz.c <<'!E!O!F!' /* Buchholz performance test. * from "A synthetic job for measuring system performance" * by W. Buchholz, IBM Syst. Journal, No. 4 1969 page 309. * * The following parameters determine size and arithmetic type of test */ #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/times.h> #define TICKS_SEC 60 /* clock ticks/second */ /* The following determine size of table and data type to use * for the compute bound test portion. */ #define N 10 #define START 100 typedef long TESTYPE; /* want 32 bit integers */ /* the following determine type I/O to be done. */ #define GETREC(x,f) fread((char *) &x, sizeof(x), 1, f) #define PUTREC(x,f) fwrite((char *) &x, sizeof(x), 1, f) #define TRUE 1 #define FALSE 0 #define BIGNUM 32766 char mas_name[] = "/tmp/Bm\0XXXXXX"; char det_name[] = "/tmp/Bd\0XXXXXX"; char nmas_name[] = "/tmp/Bn\0XXXXXX"; char ndet_name[] = "/tmp/Bo\0XXXXXX"; FILE *master, *detin, *newmas, *detout; FILE *openfile(); main() { static TESTYPE table[N*N*N+1], sum; register int j; int ratio,nmas,nmas1,ndet,ndet1,nrep; long checksum, count, rstime, retime; char card[80]; float el_stime, el_utime; extern int clean(); struct tms st_time, end_time; struct record { int key; TESTYPE sum; long check; char data[16]; } m_rec,d_rec; nmas = 0; ndet = 0; mktemp(mas_name); mktemp(det_name); mktemp(nmas_name); mktemp(ndet_name); if( signal(SIGHUP, clean) == SIG_IGN) signal(SIGHUP,SIG_IGN); if(signal(SIGINT, clean) == SIG_IGN) signal(SIGINT,SIG_IGN); for(j=1; j<= N*N*N; j++) /* initialize the table */ table[j] = START + j - 1; printf("Input: #master #detail #steps\n"); while(fgets(card, 80, stdin) != NULL) { printf("%s",card); j=sscanf(card,"%d %d %d", &nmas1, &ndet1, &nrep); if(j!=3||nmas1<0||ndet1<0||nrep<0||ndet1>nmas1) { fprintf(stderr,"ERROR:invalid input parameters\n"); continue; } count = 0; checksum = 0; if (nmas1 != nmas && nmas1 > 0) { /* Master generation */ nmas = nmas1; master = openfile(mas_name,"w"); for(j=1; j<=nmas; j++) { m_rec.sum = 0; m_rec.key = j; checksum += j; m_rec.check = checksum; sprintf(m_rec.data,"MASTER %7d",j); PUTREC(m_rec, master); } fclose(master); checksum = 0; } if (ndet1 != ndet && ndet1 > 0) { /* Detail generation */ ndet = ndet1; ratio = nmas / ndet; detout = openfile(det_name,"w"); for(j=ratio; j<=nmas; j += ratio) { d_rec.sum = 0; d_rec.key = j; checksum += j; d_rec.check = checksum; sprintf(d_rec.data, "DETAIL %7d", j); PUTREC(d_rec, detout); } fclose(detout); checksum = 0; } if (nrep==0) continue; /* Disk I/O pass */ if (nmas1 > 0 && ndet1 > 0) { master = openfile(mas_name,"r"); newmas = openfile(nmas_name,"w"); detin = openfile(det_name,"r"); detout = openfile(ndet_name,"w"); GETREC(m_rec, master); GETREC(d_rec, detin); times(&st_time); time(&rstime); while(!feof(master)) { if(m_rec.key < d_rec.key) { /* Key test */ PUTREC(m_rec, newmas); GETREC(m_rec, master); } else if(m_rec.key > d_rec.key) { fprintf(stderr,"ERROR:records out of sequence\n"); goto end_disk; } else { if(!kernel(table,nrep,&sum)) goto end_disk; m_rec.sum = sum; /* Write detail */ d_rec.sum = sum; checksum = d_rec.check; count++; PUTREC(d_rec, detout); GETREC(d_rec, detin); PUTREC(m_rec, newmas); GETREC(m_rec, master); } if(feof(detin)) d_rec.key = BIGNUM; } times(&end_time); time(&retime); if(checksum != (count * (count+1)*ratio)/ 2) fprintf(stderr,"ERROR: Checksum error\n"); end_disk: fclose(master); fclose(newmas); fclose(detin); fclose(detout); } else { /* Compute pass */ time(&rstime); times(&st_time); kernel(table,nrep,&sum); times(&end_time); time(&retime); } el_stime = (end_time.tms_stime - st_time.tms_stime)/TICKS_SEC; el_utime = (end_time.tms_utime - st_time.tms_utime)/TICKS_SEC; printf("Cpu time:%5.1f (sys) + %5.1f (usr) = %5.1f secs.\n", el_stime, el_utime, el_stime+el_utime); printf("Elapsed time:%ld secs.\n",retime-rstime); printf("loops: %d\t",nrep); printf("sum: %ld\t", sum); printf("#active: %ld\t",count); printf("checksum: %ld\n\n", checksum); } unlink(mas_name); unlink(det_name); unlink(nmas_name); unlink(ndet_name); } /* * The compute kernel sums N integers from a table of N^3 consectutive integers * beginning with START. k-th integer summed is START - 1 + K^3. * sum is checked algebraically. Kernel is repeated nrep times. */ kernel(table,nrep,sum) TESTYPE table[]; TESTYPE *sum; int nrep; { register int i,j,k; TESTYPE u, lsum; for(i=0; i<nrep; i++) { *sum = u = 0; j = 0; for(k=1; k<=N; k++) { j += 6*u + 1; *sum += table[j]; u += k; } lsum = (N * (N + 1))/ 2; if(START != (*sum - lsum * lsum) / N + 1) { fprintf(stderr,"ERROR: Compute pass arithmetic error\n"); return(FALSE); } } return(TRUE); } /* An open function with error checking */ FILE *openfile(name,acc) char *name, *acc; { register FILE *result; result = fopen(name, acc); if(result == NULL) { fprintf(stderr, "Couldn't open file: %s\n", name); exit(1); } return(result); } /* quit and remove the temporary files if we get interrupted */ clean() { fclose(master); fclose (newmas); fclose(detin); fclose (detout); unlink(mas_name); unlink(det_name); unlink(nmas_name); unlink(ndet_name); exit(2); } !E!O!F! echo x - PWB11-70 cat >PWB11-70 <<'!E!O!F!' Input: #master #detail #steps 0 0 1000 short compute test Cpu time: 0.0 (sys) + 0.0 (usr) = 0.0 secs. Elapsed time:2 secs. loops: 1000 sum: 4015 #active: 0 checksum: 0 0 0 10000 med compute bound test Cpu time: 1.0 (sys) + 6.0 (usr) = 7.0 secs. Elapsed time:25 secs. loops: 10000 sum: 4015 #active: 0 checksum: 0 0 0 50000 long compute bound test ERROR:invalid input parameters 1000 100 1 short I/O test Cpu time: 0.0 (sys) + 0.0 (usr) = 0.0 secs. Elapsed time:9 secs. loops: 1 sum: 4015 #active: 100 checksum: 50500 3000 500 1 I/O bound test Cpu time: 2.0 (sys) + 2.0 (usr) = 4.0 secs. Elapsed time:41 secs. loops: 1 sum: 4015 #active: 500 checksum: 751500 4000 700 200 long mixed test Cpu time: 15.0 (sys) + 108.0 (usr) = 123.0 secs. Elapsed time:307 secs. loops: 200 sum: 4015 #active: 800 checksum: 1602000 !E!O!F! echo x - Vax750 cat >Vax750 <<'!E!O!F!' Input: #master #detail #steps 0 0 1000 short compute test Cpu time: 0.0 (sys) + 0.0 (usr) = 0.0 secs. Elapsed time:0 secs. loops: 1000 sum: 4015 #active: 0 checksum: 0 0 0 10000 med compute bound test Cpu time: 0.0 (sys) + 2.0 (usr) = 2.0 secs. Elapsed time:6 secs. loops: 10000 sum: 4015 #active: 0 checksum: 0 0 0 50000 long compute bound test Cpu time: 1.0 (sys) + 12.0 (usr) = 13.0 secs. Elapsed time:25 secs. loops: 50000 sum: 4015 #active: 0 checksum: 0 1000 100 1 short I/O test Cpu time: 0.0 (sys) + 1.0 (usr) = 1.0 secs. Elapsed time:5 secs. loops: 1 sum: 4015 #active: 100 checksum: 50500 3000 500 1 I/O bound test Cpu time: 1.0 (sys) + 3.0 (usr) = 4.0 secs. Elapsed time:9 secs. loops: 1 sum: 4015 #active: 500 checksum: 751500 4000 700 200 long mixed test Cpu time: 6.0 (sys) + 48.0 (usr) = 54.0 secs. Elapsed time:104 secs. loops: 200 sum: 4015 #active: 800 checksum: 1602000 !E!O!F! echo x - Vax780 cat >Vax780 <<'!E!O!F!' Input: #master #detail #steps 0 0 1000 short compute test Cpu time: 0.0 (sys) + 0.0 (usr) = 0.0 secs. Elapsed time:1 secs. loops: 1000 sum: 4015 #active: 0 checksum: 0 0 0 10000 med compute bound test Cpu time: 0.0 (sys) + 1.0 (usr) = 1.0 secs. Elapsed time:1 secs. loops: 10000 sum: 4015 #active: 0 checksum: 0 0 0 50000 long compute bound test Cpu time: 0.0 (sys) + 6.0 (usr) = 6.0 secs. Elapsed time:9 secs. loops: 50000 sum: 4015 #active: 0 checksum: 0 1000 100 1 short I/O test Cpu time: 0.0 (sys) + 0.0 (usr) = 0.0 secs. Elapsed time:1 secs. loops: 1 sum: 4015 #active: 100 checksum: 50500 3000 500 1 I/O bound test Cpu time: 0.0 (sys) + 2.0 (usr) = 2.0 secs. Elapsed time:5 secs. loops: 1 sum: 4015 #active: 500 checksum: 751500 4000 700 200 long mixed test Cpu time: 3.0 (sys) + 24.0 (usr) = 27.0 secs. Elapsed time:51 secs. loops: 200 sum: 4015 #active: 800 checksum: 1602000 !E!O!F!