't is Friday, so here we go again.
I wrote the following in Intel assembler in the 1990's to check the CPU-cycles
performance of DOS vs Windows 3.1 (if memory serves), using a 486/33Mhz
processor and practically all executable code loaded in the instruction cache:
;--------------------------------------
; LOOPTIME
; Purpose:
; to determine m/c cycles versus elapsed time needed to loop
;--------------------------------------
TITLE LOOPTIME - timing program
.MODEL SMALL
.486
SSEG SEGMENT STACK
DWORD 32 DUP(?)
SSEG ENDS
DSEG SEGMENT
DUMMY BYTE ?
L_DUMMY EQU $-DUMMY
DSEG ENDS
CSEG SEGMENT 'CODE'
ASSUME CS:CSEG,SS:SSEG,DS:DSEG
MAIN PROC FAR
STI ; set hardware interrupt flag
PUSH DS
PUSH 0
MOV AX,DSEG
MOV DS,AX
; DUAL LOOPING: this takes about 1'45" to execute. <-- Note: 1 minute 45
seconds under native DOS
LOOPINIT:
MOV CX,04000h ; set LOOP1 = 16K
LOOP1:
MOV BX,0001H
LEA DX,DUMMY
PUSH CX
MOV CX,04000h ; set LOOP2 = 16K
LOOP2:
PUSH DX
PUSH CX
MOV CX,L_DUMMY
MOV AH,40H
POP CX
POP DX
LOOP LOOP2
POP CX
LOOP LOOP1
RET
MAIN ENDP
CSEG ENDS
END MAIN
This took approx 1'45" (elapsed) to execute under native DOS with a 80486/33Mhz
processor - i.e. there was a 1-to-1 correlation between the number of machine
instructions vs the number of actual 33Mhz CPU cycles.
I reran this under Windows XP from the 'command prompt' with a 3.2Ghz processor
(approx 100 times faster than a 33Mhz one), and it then took 3'48" to complete
- thus about 200 times longer (CPU-wise/elapsed) than when running under native DOS.
Moral: Use native DOS (preferably with a DOS extender) for fast PC performance.
BTW Here is a timed version of the same above (its timing 'overflows' when run
under Windoze):
;--------------------------------------
; LOOPMAC
; Purpose:
; to determine m/c cycles versus elapsed time needed to loop
; - testing macro format
;--------------------------------------
TITLE LOOPMAC- timing program
.MODEL SMALL
.486
SSEG SEGMENT STACK
DWORD 32 DUP(?)
SSEG ENDS
DSEG SEGMENT
DUMMY BYTE ?
L_DUMMY EQU $-DUMMY
HR1 DB ?
MN1 DB ?
SC1 DB ?
HN1 DB ?
HR2 DB ?
MN2 DB ?
SC2 DB ?
HN2 DB ?
HR3 DB ?
MN3 DB ?
SC3 DB ?
HN3 DB ?
PAD DB " "
MESSAGE DB "Total time taken was "
;OURS DW ?
HOURS1 DB ?
HOURS2 DB ?
; DB "hrs "
;INUTES DW ?
MINUTE1 DB ?
MINUTE2 DB ?
; DB "min "
;ECONDS DW ?
SECOND1 DB ?
SECOND2 DB ?
; DB "sec "
;UNDRTS DW ?
HUNDRT1 DB ?
HUNDRT2 DB ?
; DB "ms "
L_TIME EQU $-HOURS1
DB 0DH,0AH
L_MESSAGE EQU $-MESSAGE
TABLE DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H
DSEG ENDS
; -------------------- Macros ------------------------------------
LOOPY MACRO
LOOP2:
PUSH DX
PUSH CX
MOV CX,L_DUMMY
MOV AH,40H
POP CX
POP DX
LOOP LOOP2
ENDM
; -------------------- Macros ------------------------------------
CSEG SEGMENT 'CODE'
ASSUME CS:CSEG,SS:SSEG,DS:DSEG,ES:DSEG
MAIN PROC FAR
CLI ; clear hardware interrupt flag
PUSH DS
PUSH 0
MOV AX,DSEG
MOV DS,AX
MOV ES,AX
; DUAL LOOPING: this takes about 1'45" to execute. <-- Note: 1 minute 45
seconds under native DOS
LOOPINIT:
INIT_TIME:
MOV AH,2CH ; get time
INT 21H
MOV HR1,CH ; hours
MOV MN1,CL ; minutes
MOV SC1,DH ; seconds
MOV HN1,DL ; hundredths of a second
; MOV CX,04000h ; set LOOP1 = 16K
; MOV CX,08000h ; set LOOP1 = 32K
MOV CX,10000h ; set LOOP1 = 64K
; MOV CX,20000h ; set LOOP1 = 128K
LOOP1:
MOV BX,0001H
LEA DX,DUMMY
PUSH CX
; MOV CX,04000h ; set LOOP2 = 16K
; MOV CX,08000h ; set LOOP2 = 32K
MOV CX,10000h ; set LOOP2 = 64K
; MOV CX,20000h ; set LOOP2 = 128K
LOOPY ; invoke LOOPY macro
POP CX
LOOP LOOP1
END_TIME:
MOV AH,2CH ; get time
INT 21H
MOV HR2,CH ; hours
MOV MN2,CL ; minutes
MOV SC2,DH ; seconds
MOV HN2,DL ; hundredths of a second
COMPUTE_TIME:
MOV AL,HN2 ; hundredths of a second
SUB AL,HN1
JGE HN_OK
ADD AL,100
SUB SC2,01
JGE HN_OK
ADD SC2,60
SUB MN2,01
JGE HN_OK
ADD MN2,60
SUB HR2,01
JGE HN_OK
ADD HR2,24
HN_OK: MOV HN3,AL
MOV AL,SC2 ; seconds
SUB AL,SC1
JGE SC_OK
ADD AL,60
SUB MN2,01
JGE SC_OK
ADD MN2,60
SUB HR2,01
JGE SC_OK
ADD HR2,24
SC_OK: MOV SC3,AL
MOV AL,MN2 ; minutes
SUB AL,MN1
JGE MN_OK
ADD AL,60
SUB HR2,01
JGE MN_OK
ADD HR2,24
MN_OK: MOV MN3,AL
MOV AL,HR2 ; hours
SUB AL,HR1
JGE HR_OK
ADD AL,24
HR_OK: MOV HR3,AL
MOV DL,0AH ; divide by 10
; hours
MOV AL,HR3
MOV AH,0H
DIV DL
; MOV HOURS,AX
MOV HOURS1,AL
MOV HOURS2,AH
; minutes
MOV AL,MN3
MOV AH,0H
DIV DL
; MOV MINUTES,AX
MOV MINUTE1,AL
MOV MINUTE2,AH
; seconds
MOV AL,SC3
MOV AH,0H
DIV DL
; MOV SECONDS,AX
MOV SECOND1,AL
MOV SECOND2,AH
; hundreths
MOV AL,HN3
MOV AH,0H
DIV DL
; MOV HUNDRTS,AX
MOV HUNDRT1,AL
MOV HUNDRT2,AH
; translate to ASCII
HERE:
LEA SI,HOURS1
LEA DI,HOURS1
MOV CX,L_TIME
CLD
LEA BX,TABLE
NEXT_ONE:
LODSB
XLAT
STOSB
LOOP NEXT_ONE
DISPLAY_TIME:
MOV BX,0001H
LEA DX,MESSAGE
MOV CX,L_MESSAGE
MOV AH,40H
INT 21H
RET
MAIN ENDP
CSEG ENDS
END MAIN
I have the assembled/linkedited '*.exe' modules of the above, but do not know
how to upload them to this list. Let me know offline if you want copies.
Cheers, CP
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN