The MASM Forum Archive 2004 to 2012

Miscellaneous Forums => 16 bit DOS Programming => Topic started by: MichaelW on October 17, 2009, 06:11:14 AM

Title: Test of cycle-count macros for DOS
Post by: MichaelW on October 17, 2009, 06:11:14 AM
The attachment contains the counter2 macros modified for operation in a 16-bit DOS application, along with a minimal set of support components and a test app. The macros work as expected running under DOS on an AMD K5, and the run to run variation in the cycle counts is very low. Running under Windows 2000 on a P3, the run to run variation of several cycles is actually less than I expected. I encountered an unexpected problem running under Windows XP on the K5 system. The test app starts, but then it gets terminated before it displays anything, with no error message and nothing in the event logs. I traced the problem to the RDTSC instructions. If I eliminate them the test app runs to completion. I currently have no convenient method of determining if this is an XP problem or an XP + K5 problem.

Edit (after a cup of coffee):

I added CLI/STI to the macros and restored the alignments for refLabel and workLabel to what they are in the Windows macros (align 16). Now running under DOS on an AMD K5 or under Windows 2000 on a P3, over 10+ trials there were no run to run variations in the cycle counts. Attachment updated.
Title: Re: Test of cycle-count macros for DOS
Post by: sinsi on October 17, 2009, 06:28:11 AM
I tried the test program, booting from a floppy into DOS and got -
empty = 0, with one 9
CtBits = 45/54
CBits = 18/27

Thanks for taking the hint  :bg
Sir, I salute you :21Gun:
Title: Re: Test of cycle-count macros for DOS
Post by: MichaelW on October 17, 2009, 06:59:33 AM
Running exclusively under DOS, a CLI before the tests followed by an STI afterwards would probably eliminate some of the variation. I left this out because NTVDM will not tolerate it, but it occurs to me now that it might be possible to reliably determine when it is acceptable, and execute the CLI/STI only then.
Title: Re: Test of cycle-count macros for DOS
Post by: sinsi on October 17, 2009, 07:04:48 AM
>NTVDM will not tolerate it
Do you mean it crashes? I thought the IF was a per-process thing and windows ignored it.
Title: Re: Test of cycle-count macros for DOS
Post by: MichaelW on October 17, 2009, 07:19:53 AM
I'm asleep at the wheel again. Windows NT and later will not tolerate it in a Windows app, but NTVDM will in a DOS app.
Title: Re: Test of cycle-count macros for DOS
Post by: dedndave on October 17, 2009, 09:57:02 AM
very cool Michael   :U
thanx again

EDIT - should make this a sticky!!
(http://www.visitallan.biz/html/emote/not_worthy.gif)
Title: Re: Test of cycle-count macros for DOS
Post by: dedndave on October 17, 2009, 02:00:19 PM
Michael,
i am trying to understand the use of the codealign macro
it requires a label named code_base, yet, i see no such label in the example program
i take it this label is created by the assembler by default ?
also - will the regular assembler align not work in 16-bit ?

EDIT - oh - i found it in the macro file
the second question is still good, though - lol

one more question - aligning by 8 - is there an advantage over word-alignment of procedures in 16-bit ?
Title: Re: Test of cycle-count macros for DOS
Post by: MichaelW on October 17, 2009, 07:47:10 PM
In 16-bit code using the simplified segment directives, specifying any value greater than 2 in the align directive results in:

error A2189: invalid combination with segment alignment

I could not find any way around this short of using full segment definitions, and since I didn't want to do that, and I already had the codealign macro, I used it. The macro was actually intended for specifying alignments > 16 in 32-bit code.

The code_base label has to be at offset 0 in the code segment, and since the start of the segment is in dosctr.asm it needed to be there, and putting it there is actually more convenient.

The codealign 8 ahead of the test procedures was an afterthought that I probably should have left out. The main point is to ensure that for both procedures the call instruction has the same overhead, and I would guess that in 16-bit code an align 2 would suffice for this (or not, given that changing the loop labels in the macro from align 2 to codealign 16 made a significant difference in my tests).

Do these macros work OK on your P4, and do they work running under Windows XP?
Title: Re: Test of cycle-count macros for DOS
Post by: dedndave on October 17, 2009, 10:00:59 PM
oh yes - it runs fine on XP
as you know, my P4 prescott always yields oddball numbers
i do get some negative counts for the empty loop
but, considering my machine, i would say that is to be expected

15 cycles, empty
45 cycles, CtBits
52 cycles, CBits
0 cycles, empty
60 cycles, CtBits
52 cycles, CBits
-15 cycles, empty
60 cycles, CtBits
52 cycles, CBits
-7 cycles, empty
60 cycles, CtBits
52 cycles, CBits
15 cycles, empty
60 cycles, CtBits
38 cycles, CBits
-15 cycles, empty
60 cycles, CtBits
52 cycles, CBits
0 cycles, empty
60 cycles, CtBits
38 cycles, CBits
0 cycles, empty
75 cycles, CtBits
150 cycles, CBits

i don't know how to confine execution to a single core under 16-bit ntvdm
perhaps, it is already confined
i may put a keyboard pause in, then limit affinity with the task manager before running the tests
Title: Re: Test of cycle-count macros for DOS
Post by: MichaelW on October 18, 2009, 12:16:19 AM
Do you have any convenient way to run the test under DOS on that system?
Title: Re: Test of cycle-count macros for DOS
Post by: Magnum on October 18, 2009, 12:32:23 AM
I got this when I ran it on a floppy disk.

0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
Title: Re: Test of cycle-count macros for DOS
Post by: dedndave on October 18, 2009, 12:51:09 AM
sorry, Michael - this machine has no floppy drive
but, Steve N. (FORTRANS) could probably test it under DOS and WIN 3.1 (WOW) for you
Title: Re: Test of cycle-count macros for DOS
Post by: qWord on October 18, 2009, 01:01:27 AM
Quote from: MichaelW on October 17, 2009, 07:47:10 PMThe code_base label has to be at offset 0 in the code segment, and since the start of the segment is in dosctr.asm it needed to be there, and putting it there is actually more convenient.
I've written an similarly macro that saves such declaration (outside the macro):


IFDEF algin_zero_lbl_code
goto skip
ELSE
_TEXT SEGMENT
align_mark_code:
org 0
algin_zero_lbl_code LABEL BYTE ; pos 0 in current segment
org align_mark_code
_TEXT ENDS
_DATA SEGMENT
align_mark_data:
org 0
algin_zero_lbl_data LABEL BYTE
org align_mark_data
_DATA ENDS

ENDIF

regards, qWord
Title: Re: Test of cycle-count macros for DOS
Post by: dedndave on October 18, 2009, 01:07:23 AM
org 0 ???
that works ? - lol
Title: Re: Test of cycle-count macros for DOS
Post by: qWord on October 18, 2009, 02:17:39 AM
yes, 0 = the first by in current segment
(proofed with masm v6-10  :8))
Title: Re: Test of cycle-count macros for DOS
Post by: dedndave on October 18, 2009, 02:24:31 AM
cool - lol
i would have thought that would get you the base of the PSP or something
from what i know, org 0 sets the counter to address 0 - at least it did in 16-bit code with masm 5.10
Title: Re: Test of cycle-count macros for DOS
Post by: FORTRANS on October 18, 2009, 02:58:06 PM
Quote from: dedndave on October 18, 2009, 12:51:09 AM
sorry, Michael - this machine has no floppy drive
but, Steve N. (FORTRANS) could probably test it under DOS and WIN 3.1 (WOW) for you

Hi All,

   Quick tests, prod if more wanted.

P-III Windows 2000 Command Prompt.
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits

P-III DOS 6.20 Clean Boot.
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits
0 cycles, empty
50 cycles, CtBits
42 cycles, CBits

Pentium DOS 6.20 Clean boot (regular boot locked).
0 cycles, empty
39 cycles, CtBits
24 cycles, CBits
0 cycles, empty
39 cycles, CtBits
24 cycles, CBits
0 cycles, empty
39 cycles, CtBits
24 cycles, CBits
0 cycles, empty
39 cycles, CtBits
24 cycles, CBits
0 cycles, empty
39 cycles, CtBits
24 cycles, CBits
0 cycles, empty
39 cycles, CtBits
24 cycles, CBits
0 cycles, empty
39 cycles, CtBits
24 cycles, CBits
0 cycles, empty
39 cycles, CtBits
24 cycles, CBits


   Did not test under Win 3.11 as it did not work with the
memory managers loaded.

   And for something completely different:  This old code
does align an ORG, but with warning errors.  It looks as
if I adapted this code from something else.  I ended up
doing an ORG by hand, and not using this to avoid the
messages.


Microsoft (R) Macro Assembler Version 5.00                  10/18/9Picture File Shower                                         Page     1-3

  102 0077  1B 5B 48 24        OFF25   DB      27,'[H$'        ; Z-100 reset terminal
  103
  104                          ; buffers for data.  It was stated that these needed to be aligned on even 100H
  105                          ; boundries.  This is because of the loop counter logic being byte oriented.
  106                          IF ($-0) MOD 256
show256.ASM(98): error A2042: Constant expected
  107 0100                       org   ( $ + 256 - (($-0) MOD 256 ) )
show256.ASM(99): error A2042: Constant expected
  108                          ENDIF
  109                          ;        ORG 200H        ; Punt due to errors?
  110
  111                                                  ; High resolution buffer.
  112 0100  0200[              BUFCOL1 DB      200H DUP (?)    ; column buffers for data
  113        ??
  114             ]


HTH,

Steve N.
Title: Re: Test of cycle-count macros for DOS
Post by: FORTRANS on October 18, 2009, 03:13:13 PM
Quote from: dedndave on October 18, 2009, 02:24:31 AM
cool - lol
i would have thought that would get you the base of the PSP or something
from what i know, org 0 sets the counter to address 0 - at least it did in 16-bit code with masm 5.10

Hi Dave,

   It would give the base (start) of the PSP if used in a *.COM
style program.  You would have to set up a separate segment
directive for the PSP in an *.EXE program for that to work.
(And put the ORG in that segment.) 

Regarda,

Steve N.
Title: Re: Test of cycle-count macros for DOS
Post by: dedndave on October 18, 2009, 03:16:33 PM
hi Steve - interesting to see the tests
well - no matter which segment you are in, i thought ORG set the address counter
i can see how it may work differently in FLAT model programs, however
it has been so long since i have written a complicated 16-bit EXE - lol
if i remember, one of the registers has the PSP segment in it at startup (DS or ES i think - maybe both)
Title: Re: Test of cycle-count macros for DOS
Post by: FORTRANS on October 18, 2009, 07:16:36 PM
Quote from: dedndave on October 18, 2009, 03:16:33 PM
hi Steve - interesting to see the tests

   Okay.

Quote
well - no matter which segment you are in, i thought ORG set the address counter

   Right.  But if you wanted to address the elements of the
PSP, for example, in an EXE program, you have to put the
ORG in the right segment.  (Well, no you don't, but then
you have have to lie to the assembler.  If I remember
correctly.)

Quote
i can see how it may work differently in FLAT model programs, however
it has been so long since i have written a complicated 16-bit EXE - lol
if i remember, one of the registers has the PSP segment in it at startup (DS or ES i think - maybe both)

   Yup, both DS and ES in an EXE.  And all four in a COM
program.

Regards,

Steve N.
Title: Re: Test of cycle-count macros for DOS
Post by: Rockphorr on October 20, 2009, 06:27:26 AM
Hi
I will try it on my old p2 with win95osr2.

I use
Quote_TEXT segment byte public 'code'
in my libs to write just after the app codeseg.
Title: Re: Test of cycle-count macros for DOS
Post by: Rockphorr on October 20, 2009, 06:39:02 AM
Quote from: MichaelW on October 17, 2009, 07:47:10 PM
In 16-bit code using the simplified segment directives, specifying any value greater than 2 in the align directive results in:

error A2189: invalid combination with segment alignment

I could not find any way around this short of using full segment definitions, and since I didn't want to do that, and I already had the codealign macro, I used it. The macro was actually intended for specifying alignments > 16 in 32-bit code.

The code_base label has to be at offset 0 in the code segment, and since the start of the segment is in dosctr.asm it needed to be there, and putting it there is actually more convenient.

The codealign 8 ahead of the test procedures was an afterthought that I probably should have left out. The main point is to ensure that for both procedures the call instruction has the same overhead, and I would guess that in 16-bit code an align 2 would suffice for this (or not, given that changing the loop labels in the macro from align 2 to codealign 16 made a significant difference in my tests).

Do these macros work OK on your P4, and do they work running under Windows XP?



An align for the first module segment is 16 by default.
may be a simple solution is just put an obj with code_base on fisrst place in the linker line.



Title: Re: Test of cycle-count macros for DOS
Post by: dedndave on October 20, 2009, 08:49:31 AM
i always used

_TEXT SEGMENT WORD PUBLIC 'CODE'
_TEXT ENDS

with the WORD align type, you can use the EVEN directive to word-align code
it generates NOP's to align in segments with 'CODE' class
you cannot use the EVEN directive if the segment align type is BYTE
with older processors under DOS, aligning code to higher order addresses didn't make a difference
i don't know if that is true with pentiums
to 16-align the segment, you could use

_TEXT SEGMENT PARA PUBLIC 'CODE'
_TEXT ENDS

since masm version 5.10, a few parameters have been added to the SEGMENT directive
Title: Re: Test of cycle-count macros for DOS
Post by: FORTRANS on October 20, 2009, 01:22:04 PM
Hi Dave,

   Just reading through a course book to find out some things
about the simplified directives, and read up on SEGMENT as well.
It said that the default alignment was PARA (16 byte) for .8086
and DWORD for .386.

Steve