📄 bench1.cpp
字号:
//Filename: BENCH1.CPP
//"WINBENCH" Generated by WindowsMAKER Professional
//Author: Martin Heller
/* Note: This project uses MFC and it also uses threads. It doesn't use MFC from
threads in production, however, so it is safe. When building for NT, define
_NTWIN and WIN32, and choose the multi-threaded libraries. If you get an error
when you link, rebuild the MFC library NAFXCW.LIB to use threads, i.e. go to
the MFC\SRC directory and issue:
NMAKE OPT=/MT DEBUG=0 CODEVIEW=0
-- MH
*/
#include <afxwin.h>
#include <afxdlgs.h>
#include "NTBENCH.H"
#include <time.h>
#include <string.h>
#include <direct.h>
WMPDEBUG
#include "BENCH1.WMC"
extern void OkMsgBox (char *szCaption, char *szFormat,...);
// user defined code
static double version = 0.82;
int bpp=0,rastercaps=0,sizepalette=0,numreserved=0;
CString MachineDescription;
struct Benchargs {
char *bname;
char *strp;
void(*funcp)();
CWnd *pDlg;
HANDLE hWaitFor;
};
long DoBench(char *bname,char *strp,void(*funcp)(),CWnd * pDlg)
{
long stime; /* Start time */
long etime; /* End time */
long time; /* Elapse time */
int secs; /* Seconds */
int hunds; /* 1/100 seconds */
char temp1[100],temp2[20];
MSG msg;
sprintf(temp1,"%4s %-22s ", bname, strp);
stime = clock();
(*funcp)();
etime = clock();
time = etime - stime;
time = (long)(time / ((double)CLOCKS_PER_SEC/100.0));
secs = int(time / 100);
hunds = int(time % 100);
sprintf(temp2,"%4d.%02d secs\n", secs, hunds);
strcat(temp1,temp2);
pDlg->SetDlgItemText(id_tx_status,temp1);
TRACE(temp1);
PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE); //breathe a little
return time;
}
extern char drive[];
extern int filesize;
extern UINT blocksize;
extern char buffer[];
extern char fillchar;
extern void diskio0(void);
extern void diskio1(void);
extern void diskio2(void);
extern void diskio3(void);
extern void diskio4(void);
extern void diskio5(void);
extern int file_error;
long DiskTimes[6];
CString DoDiskBench(CWnd *pDlg,int nblocks,int nreps,char *ddrive)
{
CString answer;
long Wtime;
char temp[30];
memset(buffer,fillchar,blocksize);
filesize = nblocks;
strcpy(drive,ddrive);
ASSERT(nblocks>1);
ASSERT(nreps>0);
ASSERT(blocksize==4096);
//accumulate time in hundredths of a second
Wtime = DiskTimes[0] = DoBench("I0","Create file",diskio0,pDlg);
for(int i=0;i<nreps;i++) {
Wtime+= DiskTimes[1] = DoBench("I1","Sequential Write Test",diskio1,pDlg);
Wtime+= DiskTimes[2] = DoBench("I2","Sequential Read Test ",diskio2,pDlg);
Wtime+= DiskTimes[3] = DoBench("I3","Random Write Test ",diskio3,pDlg);
Wtime+= DiskTimes[4] = DoBench("I4","Random Read Test ",diskio4,pDlg);
}
Wtime+= DiskTimes[5] = DoBench("I5","Delete file",diskio5,pDlg);
if(file_error)
strcpy(temp,"A disk error occurred");
else
sprintf(temp,"Total Disk test time %ld.%ld s",Wtime/100,Wtime%100);
pDlg->SetDlgItemText(id_tx_status,temp);
//turn time into MBytes/second
if(Wtime<=0) Wtime=1000; //protect against divide by 0
double mbytes_per_sec =(nblocks * (double)blocksize * 0.0004 * nreps / (double)Wtime);
if(file_error)
strcpy(temp,"Error");
else
sprintf(temp,"%.4g",mbytes_per_sec);
answer=temp;
return(answer);
}
extern void video0(void);
extern void video1(void);
extern void video2(void);
extern void video3(void);
extern void video4(void);
extern void video5(void);
CWnd *pParent;
extern long vid1pix,vid2pix,vid3pix,vid4pix;
extern long screenarea;
long VideoTimes[6];
CString DoVideoBench(CWnd *pDlg,int nreps)
{
CString answer;
long Wtime;
long TotalPixels;
char temp[30];
ASSERT(nreps>0);
pParent=pDlg;
//accumulate time in hundredths of a second
Wtime = VideoTimes[0] = DoBench("V0","Create Window",video0,pDlg);
for(int i=0;i<nreps;i++) {
Wtime+= VideoTimes[1] = DoBench("V1","Character Scrolling Test",video1,pDlg);
Wtime+= VideoTimes[2] = DoBench("V2","Line/Curve Drawing Test ",video2,pDlg);
Wtime+= VideoTimes[3] = DoBench("V3","Filled Object Test ",video3,pDlg);
VideoTimes[4] = DoBench("V4","Color Display Test ",video4,pDlg);
//color display excluded from total time
}
Wtime+= VideoTimes[5] = DoBench("V5","Destroy Window",video5,pDlg);
sprintf(temp,"Total Video test time %ld.%ld s",Wtime/100,Wtime%100);
pDlg->SetDlgItemText(id_tx_status,temp);
//turn time into KPixels/second
if(Wtime<=0) Wtime=1000; //protect against divide by 0
//count 1 screen each for window creation and destruction, plus
//routines' record of number of pixels written
TotalPixels=2L*screenarea + vid1pix*nreps //multiply by nreps since vid1pix reset each rep
+ vid2pix*nreps + vid3pix*nreps
/* + vid4pix*nreps*/; //color display excluded from total pixels
double mpixels_per_sec =(1.0e-6 * TotalPixels / ((double)Wtime/100.0));
sprintf(temp,"%.4g",mpixels_per_sec);
answer=temp;
return(answer);
}
#ifdef WIN32
unsigned long DoBenchThread(void *bargs)
{
long TTime;
Benchargs *args = (Benchargs *)bargs;
DWORD rc=WaitForSingleObject(args->hWaitFor,10000);
TRACE("DoBenchThread: done waiting for event, rc %d\n",rc);
TTime=DoBench(args->bname,args->strp,args->funcp,args->pDlg);
TRACE("DoBenchThread: bench done, time is %d\n",TTime);
ExitThread(TTime);
return(TTime);
}
#endif
extern "C" void whetd(void);
const MAXTHREADS = 63;
CString DoWhetstone(CWnd *pDlg,int nthreads,int nreps)
{
char temp[30];
CString answer;
long Wtime=0;
#ifdef WIN32
MSG msg;
DWORD dw;
if(nthreads>1) {
HANDLE hWait,hThread[MAXTHREADS];
unsigned long id[MAXTHREADS];
Benchargs args;
hWait=CreateEvent(NULL,TRUE,FALSE,NULL); //manual reset, initially false
ASSERT(hWait);
args.bname="WD";
args.strp="Whetstone (double)";
args.funcp=whetd;
args.pDlg=pDlg;
args.hWaitFor=hWait;
for(int i=0;i<nreps;i++) {
long avg;
unsigned long exitcode;
for(int j=0; j<nthreads; j++)
hThread[j]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DoBenchThread,&args,NULL,&id[j]);
PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE);
Sleep(1000); //allow time for thread creation
PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE);
BOOL rc=SetEvent(hWait); //release all threads at once
ASSERT(rc);
//Wait for all threads to complete and get their results
TRACE("DoWhetstone: about to wait for threads\n");
for(j=0; j<nthreads; j++) {
do
{
PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE);
dw=WaitForSingleObject(hThread[j],200);
}
while (dw);
}
TRACE("DoWhetstone: done waiting for threads, dw %d\n",dw);
avg = 0;
for(j=0; j<nthreads; j++) {
GetExitCodeThread(hThread[j],&exitcode);
avg += exitcode;
}
avg /= nthreads;
Wtime += avg;
ResetEvent(hWait);
} //for nreps
sprintf(temp,"%.4g",(nreps * nthreads * 10.0 / (Wtime/100.0)));
answer=temp;
return(answer);
} //if nthreads>1
#endif
for(int i=0;i<nreps;i++) {
Wtime += DoBench("WD","Whetstone (double)",whetd,pDlg);
}
if(Wtime<=0) Wtime=1000; //protect against divide by 0
sprintf(temp,"%.4g",(nreps * 10.0 / (Wtime/100.0)));
answer=temp;
return(answer);
}
extern "C" void dhry(void);
CString DoDhrystone(CWnd *pDlg,int nthreads,int nreps)
{
char temp[30];
CString answer;
long Wtime=0;
#ifdef WIN32
MSG msg;
DWORD dw;
if(nthreads>1) {
HANDLE hWait,hThread[MAXTHREADS];
unsigned long id[MAXTHREADS];
Benchargs args;
hWait=CreateEvent(NULL,TRUE,FALSE,NULL); //manual reset, initially false
ASSERT(hWait);
args.bname="DR";
args.strp="Dhrystone";
args.funcp=dhry;
args.pDlg=pDlg;
args.hWaitFor=hWait;
for(int i=0;i<nreps;i++) {
long avg;
unsigned long exitcode;
for(int j=0; j<nthreads; j++)
hThread[j]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DoBenchThread,&args,NULL,&id[j]);
PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE);
Sleep(1000); //allow time for thread creation
PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE);
BOOL rc=SetEvent(hWait); //release all threads at once
ASSERT(rc);
//Wait for all threads to complete and get their results
TRACE("DoDhrystone: about to wait for threads\n");
for(j=0; j<nthreads; j++) {
do
{
PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE);
dw=WaitForSingleObject(hThread[j],200);
}
while (dw);
}
TRACE("DoDhrystone: done waiting for threads, dw %d\n",dw);
avg = 0;
for(j=0; j<nthreads; j++) {
GetExitCodeThread(hThread[j],&exitcode);
avg += exitcode;
}
avg /= nthreads;
Wtime += avg;
ResetEvent(hWait);
} //for nreps
sprintf(temp,"%.4g",(nreps * nthreads * 200.0 / (Wtime/100.0)));
answer=temp;
return(answer);
} //if nthreads>1
#endif
for(int i=0;i<nreps;i++) {
Wtime += DoBench("DR","Dhrystone",dhry,pDlg);
}
#ifdef WIN32
double mulfact=200.0;
#else
double mulfact=32.0;
#endif
if(Wtime<=0) Wtime=1000; //protect against divide by 0
sprintf(temp,"%.4g",(nreps * mulfact / (Wtime/100.0)));
answer=temp;
return(answer);
}
static int ResultThreads;
static int ResultBlocks;
static int ResultReps;
static char ResultDrive[4];
static CString ResultKDhrys;
static CString ResultKWhets;
static CString ResultKBytes;
static CString ResultKVideo;
BOOL RunBenchMarks(CWnd *pWnd, BOOL fDhry, BOOL fWhet, BOOL fDisk, BOOL fVideo)
{
char ddrive[4]="";
int nthreads,nblocks,nreps;
CString KDhrys,KWhets,KBytes,KVideo;
//get handle for dialog window (child of main window)
CWnd *pDlg = pWnd->GetTopWindow();
if(!pDlg)
OkMsgBox("Error","GetTopWindow failed");
//get stuff from controls
int status=pDlg->DlgDirSelect(ddrive,id_cb_drive);
if(!status)
OkMsgBox("Error","DlgDirSelect failed");
if(!lstrlen(ddrive)) {
OkMsgBox("Error","DlgDirSelect did not update drive string, using C:");
lstrcpy(ddrive,"c:");
}
/* NOTE: MFC Version 2.1 has a bug in CWnd::DlgDirSelect that will cause it to
fail. To fix the bug, edit AFXWIN2.INL: in the definition for CWnd::DlgDirSelect,
change INT_MAX to MAX_PATH. Then recompile BENCH1.CPP --mh */
// OkMsgBox("DEBUG","ddrive is <%s>",ddrive);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -