'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

Reply via email to