home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-09-09 | 63.0 KB | 1,781 lines |
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- *-------------------------------------------------------------*
- | C NEWS - International C Newsletter, Compiler review, and |
- | tutorial. |
- *-------------------------------------------------------------*
-
-
- Table of Contents
-
- The Heap: Messages from the Editor ..........................2
- by Barry Lynch
-
- Memory Models ...............................................4
- by Bill Mayne
-
- Public Domain Software Review ..............................20
- by Barry Lynch (ROFF)
-
- C Software from the C BBS ..................................21
- by Arnold Cherdak (FILECHK)
-
- Article Submission Standards ................................23
-
- Address's ...................................................24
-
- Index .......................................................25
-
- Distribution Points .........................................27
-
- User Response Form ..........................................28
-
-
- C News is an electronic journal published by the C BBS in
- Burke, VA on a monthly basis. The subject for C News is the C
- programming language, as well as any derivatives like C++.
- All readers are encouraged to submit articles, reviews, or
- comments for submission. C News is freely distributed, but
- can not be sold for a profit, or cannot have a charge assessed
- to cover distribution costs. To do so is in direct violation
- of the License agreement. Copies of which are available from
- the C BBS. This publication is Copyrighted under U.S
- Copyright Law.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 1
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- The HEAP: Messages from the Editor by Barry Lynch
-
- Well, I am back after 10 days in the wilds of Canada, no
- computers, sports or work to worry about. I highly recommend
- that everyone take time off from there work and hobbies. It
- is amazing what a little fresh air can do for the mind.
-
-
- LACK OF FEEDBACK
-
- While I was away I spent some time pondering the future
- and status of "C News". One of the problems that I see: is
- the lack of feedback on the articles and reviews contained
- within C News. Numerous individuals have spent hours writing
- code, and an accompanying article for no financial reward. Is
- it too much to ask, to fill out the questionnaire and send it
- in? And if you have questions about some of the code
- included, why not take the time to ask the author?
-
- C News is for you the reader, but it will not survive if
- the communication is not two-way. I think that I can safely
- say that some of the authors are a little miffed at why there
- has not been any feedback. Please, take the time to offer some
- comments.
-
- Which brings me to another point: Letters to the Editor.
- At both of the C BBS Users meetings held to date, a suggestion
- has been placed on the table regarding a "Letters to the
- Editor" column for C News. I agree that it would be a good
- idea, but once again no letters. Let's at least see one per
- issue!! <Or do I have to resort to "Creating" mail to start a
- column!!>
-
- While we are on the subject of writing and lack of
- feedback. One of the individuals that has taken the time to
- write for C News is: Bill Mayne. Bill currently has the lead
- article in C news this month on memory models. Bill also has
- an article in the September issue of "Computer Language". The
- article is called: To Parse or not Parse. Bill explores the
- use of the main() command line arguments. If you can, take
- the time to read the article and offer Bill comments or
- congratulations on a job well done. Bill is a regular user
- here at the C BBS, and answers mail left to him as time
- permits.
-
- Another user that has taken the time to write is Arnie
- Cherdak. Arnie wrote the article on Database's in C in Issue
- 10. The article was written to be used as an interactive
- tutorial. Exercises were included, with the intended result
- of readers sending in the code they wrote. To date no one has
- commented on the article or shown any code. Once again, lack
- of feedback.
-
-
-
-
-
-
-
- Page 2
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- ROFF
-
- Well that is all for now on the subject of feedback I
- think I have made my point. You may notice that C News has a
- new format beginning with this issue. I have started to use
- ROFF, a PC based version of the UNIX Roff utility. As I
- become more familiar with the software, the format may change
- yet again. The goal is to have an automatic C News or any
- newsletter for matter - generator. Roff is part of the
- answer, and some additional code is needed. Suffice it to say
- that the use of Roff will provide a neater end product, and
- free up more of my time for editing and writing. If anyone is
- interested in Roff, I have two versions of the program here on
- the C BBS. See Public Domain Software Reviews for more
- information.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 3
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- CHOOSING A MEMORY MODEL by Bill Mayne
-
- ABSTRACT: The meaning of the "near", "far", and "huge"
- keywords specifying pointer types and how these are related to
- the various memory models available to C programmers using the
- 80x86 family of processors used in IBM and compatible PCs and
- their successors is explained. A simple bench mark which
- illustrates the affect of memory model selection on code size
- and execution time is shown. Coding examples show how to use
- preprocessor symbols and the #if directive to handle cases
- where source code must be modified according the memory model
- in use. The compilers used are Microsoft C (MSC) versions 4.0
- and 5.0 and Turbo C version 1.5.
-
- Based on an understanding of pointer types and memory
- models, confirmed by the results of the bench mark guidelines
- for the selection of the best memory model for a program are
- given.
-
- ACKNOWLEDGEMENT: Thanks to Jerry Zeisler, who sparked
- interest in the subject of this article in a "conversation" on
- the C BBS and helped with the bench mark by compiling them
- with Turbo C. Thanks also to Barry Lynch, editor of the C
- News and sysop of the C BBS for his encouragement, assistance
- with file transfers, and running a fine BBS for the discussion
- of C related issues.
-
- 1. INTRODUCTION
-
- The use of the "near", "far", and "huge" keywords when
- declaring pointers and the selection of a memory model for a
- program written in C is a problem unique to the 80x86 family
- of processors because these are related to the segment:offset
- addressing scheme used in this architecture. Before
- discussing the advantages and disadvantages of the various
- options available, it is useful to briefly describe this
- scheme for those not already familiar with the machine
- language of the 80x86 architecture. Experienced 80x86
- programmers may wish to skip section 1.1, which explains the
- various types of pointers, and go directly to 1.2, which
- explains memory models. All of the information from sections
- 1.1 and 1.2 except a few historical asides and other comments
- is in the Microsoft C User's Guide.
-
- 1.1 80x86 Addresses and Pointer Types
-
- The 80x86 family of processors used in IBM and compatible
- PCs are 16 bit processors which are descendents of the 8080 or
- its spin-off, the Z80 used in earlier CP/M machines. A 16-bit
- machine is so called because its word size is 16 bits.
- Usually, but not always, the size of a pointer, word, and
- integer are the same. The 80x86 family is one of the
- exceptions. A 16 bit word can hold only 2**16 or 64K distinct
- addresses. In 80x86 processors, as in most micros and many
- larger processors, the unit of memory addressed is a byte.
-
-
-
-
-
- Page 4
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- The address of larger units like words are given by the
- address of their first byte, which may be required to be on
- certain boundaries such as even numbered addresses or
- multiples of the word size. (There are machines which use
- word addressing. This has advantages especially for
- scientific/engineering "number crunchers". It is not so good
- for handling character data.)
-
- When the 8080 and Z80 first came out, memory was much
- more expensive and being able to address 64K was thought to be
- sufficient. Another consideration was that limiting addresses
- to 16 bits made the construction of memories simpler and
- cheaper, and early microprocessors were imbedded in other
- systems for control purposes and did not need so much memory.
- The use of microprocessors for data processing applications in
- micro computers came later. The term "Personal Computer" or
- PC was not yet in common usage.
-
- As an additional historical note, mainframes of the time
- were designed with much larger address spaces, but still small
- by the standards of today and the near future. The IBM 360
- and 370 which had 32 bit processors only used 24 for
- addressing, limiting addressable memory to 16M even for these
- large machines. Already some PCs using extended memory have
- that much. By contrast, IBM mainframes in use today have the
- option of "extended architecture" or XA, using 31 bits for
- addresses, and the next wave called "Enterprise System
- Architecture" or ESA adds another 12. The amount of storage
- which can be addressed by 43 bits is truly immense, 2**43 or
- about 8.8e12, more than any main storage we are likely to see
- for a long time. Even so, such large address spaces are
- actually useful since nearly all mainframes have the hardware
- and software to support virtual memory.
-
- When the price of memory came down and the need for a
- larger address space became important, but 16-bit
- microprocessors were still the norm, designers decided to use
- a segmented memory architecture. Segments would contain 64K
- bytes each, so the relative position of a byte within a
- segment could still be represented by a 16 bit register.
- Extra registers were added to address the segments. For
- flexibility, segments were allowed to start on any 16 byte
- "paragraph" boundary. The 80x86 has registers for addressing
- 4 segments. They are CS ("code segment"), DS ("data
- segment"), SS ("stack segment"), and ES ("extra segment").
- The names reflect the way they are normally used. A segment
- register gives the address of the first paragraph of a
- segment, shifted right 4 bits to fit within a 16 bit word. To
- compute an actual address the segment is shifted left 4 bits
- to convert it to a byte address and then the offset is added
- to address any of the 64K bytes within the segment. Most
- programs, whether written in assembly language or a compiled
- language take advantage of the registers and make things
- cleaner by putting code, data and stack into separate segments
- addressed by the registers named for those purposes. (It is
-
-
-
-
-
- Page 5
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- true that the stack contains data, and for that matter code
- itself is a kind of data, but the conventional distinctions
- are useful.)
-
- Normally such details of machine architecture are only of
- concern to the assembly language programmer, but the processor
- architecture does influence part of the compiler design. C
- programmers who wish to understand the reasons for such design
- decisions and in particular architecture specific details of
- pointer type and memory model need to understand them.
-
- In machine language it is very convenient if all the
- memory referenced lies within a segment whose address is
- already loaded in the appropriate register. With the segment
- implied, only the 16 bits of the offset must actually be
- included in the pointer. Such a pointer is called a "near"
- pointer. If, on the other hand, the code or data referenced
- does not all lie within a 64K segment, it is necessary to
- specify the segment as well as the offset, and a "far" pointer
- is required. This is significant not only for space (far
- pointers requiring four bytes instead of two), but for
- performance. At the machine language level use of far
- pointers requires the values of segment registers to be
- swapped every time a different segment is accessed. Not only
- does an actual pointer take up more space, so does the code to
- manipulate it. The extra instructions also increase the
- execution time. And this applies not only to explicit pointer
- arithemetic, but to array references, sometimes global
- variable references and in other situations involving implicit
- address calculations.
-
- Far pointers are used for data when a program references
- more than 64K of data in total, but it is still convenient if
- each array or structure fits within a segment. Then the
- segment address used can be selected so that the address of
- all elements of the array or structure can be computed without
- changing the segment part of the address. If even this
- restriction must be removed a "huge" pointer is required.
- Huge pointers are four bytes long, just like far pointers, but
- arithmetic with huge pointers requires extra steps (and
- code). Both huge and far pointers follow the rule, common in
- microprocessors, of storing the least signicant byte first.
- The first word of a far pointer is the offset and the second
- word is the segment. This is important to know if you must
- construct a far pointer from its components, or decompose one
- into its segment and offset parts. A macro in Listing 1 shows
- how to do the former, and the library macros FP_SEG and FP_OFF
- do the latter. By the way, the segment and offset are also
- each stored least significant byte first, but the
- implementation of shifting and arithmetic in C take care of
- this for you and you don't need to be concerned about it.
-
- Since offsets into code are not used in this way, the
- "huge" keyword applies only to pointers to data, including
- array names.
-
-
-
-
-
- Page 6
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- Assembly language programmers must be directly concerned
- with considerations such as those above. C programmers have
- it a little easier, since the C compiler automatically takes
- care of generating addresses and swapping segment registers.
- Still, the programmer concerned with efficiency should
- understand what is required and control the selection of
- pointer types to produce the most efficient code compatible
- with other goals such as ease of programming and
- maintainability.
-
- 1.2 Memory Models
-
- The term "memory model" simply refers to the combination
- of defaults for code and data pointers. Though individual
- pointers may be explicitly declared "near", "far", or "huge",
- the memory model used is very important to program design. It
- partly determines the amount of code and/or data a program can
- address. In addition, as the bench mark in a later section
- shows, the selection of a memory model may have important
- implications for the size and efficiency of the generated
- code. As a rule, it is better to use the smallest pointer
- which will work. Use "near" in preference to "far" and use
- "huge" only if absolutely necessary.
-
- In the small memory model, both the code and data are
- addressed by near pointers. Small model programs are thus
- limited to a total of 64K of code and 64K or data, or a total
- of 128K. Most programs fit within this limit, and it is the
- most efficient, so it is the default.
-
- Medium model programs use near pointers for data and far
- pointers for code. They can therefore have only 64K of data,
- but the amount of code is limited only by available memory.
- The medium model is preferred by the integrated environment of
- Quick C, but is otherwise not often useful for hobbyist
- programmers. It takes a rather large program to exceed 64K of
- code, and most that do probably also exceed 64K of data and
- thus need the large or huge model. However, since references
- to data are executed much more frequently than far references
- to code the medium model does have quite a performance
- advantage over large in those cases where it does fit the
- requirements.
-
- Compact model programs use far pointers for data and near
- pointers for code. This model is good for programs which
- allocate a lot of data, but which have less than 64K of code.
- A common example would be a simple editor which stores a whole
- file in memory as an array or linked list.
-
- The advantage of the compact model over the large model
- is usually less than the advantage of medium over large, but
- the choice is almost always between compact and large or
- between medium and large, hardly ever between compact and
- medium.
-
-
-
-
-
-
- Page 7
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- Large model programs use far pointers for both data and
- code. They can have any amount of code and/or data which will
- fit in memory, in any combination. The only restriction is
- that individual arrays or structures cannot exceed 64K.
-
- The huge model uses far pointers for code and huge
- pointers for data and is thus restricted only by the amount of
- storage available. It is also the least efficient, and is
- rarely needed.
-
- The tiny memory model, which is an option with Turbo C
- but not with Microsoft is similar to small. Both code and
- data pointers are near pointers, but, in addition, all
- segments are assumed to be the same, that is the total data
- and code is restricted to 64K. This might yield smaller
- and/or faster code in some cases, if the compiler took
- advantage of it. In the simple bench mark given below no
- significant difference was found.
-
- Another important design consideration is that the
- library routines will assume the default types according to
- the memory model in use. Under MSC release 4.0 there is a set
- a libraries for each memory model, and the linker
- automatically selects the set matching the .OBJ files linked.
- MSC 5.0 may be installed with combined libraries, but there
- are still separate versions of library routines for each
- installed memory model. (Mixing memory models and even more
- exotic options are possible, but such advanced topics are not
- covered here.)
-
- For example, memcpy() will expect both pointer arguments
- to be either near or far pointers, according to the memory
- model in use. If it is necessary to use a far pointer to
- reference a block of memory to be copied in a program which
- otherwise uses near pointers an alternative must be provided,
- either in line or by a specially written function which has
- different name. The coding example in Listing 1 shows a
- simple but realistic case in which this is necessary. The
- function cmdargs() needs to build a far pointer to the
- unparsed command line arguments in the program segment prefix
- and use this to copy the argument string to a buffer supplied
- by the calling program. If the source code is compiled using
- the small or medium memory model memcpy() cannot be used. In
- that case in line code is selected. The decision is made at
- compile time by testing the preprocessor variables which
- identify the memory model. Since the symbol which tells the
- preprocessor that the compact, large, or huge model is in use
- is only defined when using MSC the version with in line code,
- which will actually work with any memory model is the default
- (the #else case.)
-
- 2. GUIDELINES FOR MEMORY MODEL SELECTION
-
- Many C programmers find the selection of memory model a
- confusing or even mysterious issue. The default small model
-
-
-
-
-
- Page 8
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- is sufficient most of the time, so beginners can put off
- having to consider memory models at all. But there comes a
- time as programs and/or the quantity of data grow that other
- models are necessary. Rather than take the coward's way out
- and simply resort to using large or huge all the time, which
- some have done, the wise programmer should understand all the
- issues and pick the best memory model for the job.
-
- Even in this age of cheap hardware and abundant
- resources, it may makes sense to make the best choice you can
- to minimize the use of resources. A smaller .EXE file will
- obviously load faster, and for many programs load time is
- significant, especially if you are loading from a floppy
- disk. Also, with 360K floppies keeping the .EXE file size
- down may make the difference between being able to keep the
- program and data all on one floppy. Looking at it yet another
- way, it may make the difference between being able to put a
- frequently used program in a RAM disk or having to load from a
- hard disk or worse yet a floppy. And needless to say, if you
- want to either make your program resident or shell to DOS from
- it it is worthwhile to conserve both code and data space. If
- nothing else, keeping the code size down leaves more room for
- data, and you never know when you may need it.
-
- Most of the time, the choice comes down to selecting the
- model which the program requires. The main purpose of this
- article is to help users avoid erring on the side of caution
- by automatically going to the large model as soon as they run
- out of space with small.
-
- Rarely, performance considerations may be so important
- that an advance determination of program design for a
- particular model is worthwhile, and in that case it is even
- more important to have a good idea of the trade offs
- involved.
-
- 2.1 Determining the Minimum Model Required
-
- Assuming you are not willing to design a program around
- the choice of memory model, the problem comes down to
- selecting a memory model for a program which is already
- designed and possibly coded. As noted in 1.2, the best choice
- is the one which uses the smallest pointers which will do.
-
- 2.1.1 Code Pointer Requirements
-
- The size of code pointer required is easy to determine
- and may constrain the choice of memory model. If a program,
- counting all library functions will fit in 64K or less of code
- space, use the small or compact model, otherwise medium,
- large, or huge.
-
- The code part of most small programs obviously fit in
- 64K. For extremely large programs it may obviously exceed
- that. For anything in between the decision is less clear and
-
-
-
-
-
- Page 9
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- extremely difficult to estimate. Fortunately, the decision is
- always a clear go or no go and the linker will tell you.
- Unless the program is very big, it is best to start by
- compiling all functions using the small or compact model. If
- the 64K limit is exceeded the linker will give a clear error
- message. (If you ever exceed 64K in a single source file the
- compiler would catch that, but shame on you. Modularize!)
-
- Since few if any functions need to be coded differently
- to switch to one of the larger models the chances are that all
- you will be required to do when and if you find it necessary
- will be to recompile all functions using one of the larger
- models and relink. If you have a make file for the project
- that should be simple indeed.
-
- In those rare instances where it is necessary to modify
- source code according to memory model, consider coding so that
- you can compile using any memory model. It is almost
- inconceivable that the size of the code pointer will be
- critical in the source program, so there are really only two
- cases to consider, near and far data pointers.
-
- With MSC coding for both possibilities is easy because an
- automatically defined preprocessor symbol tells the
- preprocessor which model is being used, and this can be used
- with the #if directive to select between alternative versions
- of the affected parts of the source code. The symbol is
- M_I86xM, where "x" is the one character identifier of the
- model in use: M_I86SM for small, M_I86MM for medium, M_I86CM
- for compact, M_I86LM for large, and M_I86HM for huge. For all
- models except huge the symbol for the corresponding model will
- be defined and all others being undefined. Huge is a special
- case, where both M_I86HM (as expected) and M_I86LM are
- defined. Perhaps this is because the huge model is an
- extension of the large model.
-
- Listing 1 shows a simple but realistic case where these
- symbols are used to select code based on memory model.
- Listing 2 is a little more contrived, selecting only a string
- to be displayed, but it checks all models. Note that if the
- difference between large and huge makes a difference at the
- source code level you must not conclude that the large model
- is the one in use just because M_I86LM is defined. It could
- be that M_I86HM is also defined, indicating huge. That's why
- the code in Listing 2 checks M_I86HM before M_I86LM.
-
- The amount of code is fixed. If you are able to get a
- clean link you never need worry that a decision to use the
- small or compact model will come back to haunt you, and your
- resulting .EXE file will be smaller, sometimes much smaller.
- Jerry Zeisler, who helped in the preparation of this article
- by compiling and linking the bench mark using Turbo C 1.5
- reported that when he was forced to go from the small to the
- large model for a program the .EXE file went from 71K to
- 161K. Using either medium or compact according to the
-
-
-
-
-
- Page 10
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- requirements would have made the jump less drastic, but it
- does go to shown that once you cross the line from small to
- another model you do pay a price in space.
-
- 2.1.2 Data Pointer Requirements
-
- Finding the size of data pointer required is not as
- clear-cut as determining whether or not a near code pointer
- will suffice. The amount of a storage a program will need at
- run time cannot be determined in advance by the compiler or
- linker in every case. Since C is a semi block structured
- language automatic variables are allocated on block entry, and
- the total required varies with the depth and order of block
- entries. This does not depend only upon the static structure
- of your program. It may also depend upon the data each time
- you run it. Sometimes you can arrive at a maximum, but for a
- program of any complexity it would be a tedious and error
- prone process requiring a lot of knowledge of your compiler
- implementation. If the program uses recursion it may not even
- be possible.
-
- Even when there is no recursion the uncertainty
- concerning data space requirements may be a problem in a
- program which allocates heap storage using malloc() or similar
- functions, since this is even less predictable. This puts a
- greater burden on the programmer, and I don't offer any hard
- and fast rules here.
-
- If you can determine that 64K of data will always be
- sufficient try the small model first, going to medium if
- necessary because of the code size. Otherwise use compact if
- possible, going to large if the code size requires it.
-
- Use huge only as a last resort, as it is the least
- efficient, especially with MSC 4.0. You can almost always
- determine ahead of time whether or not any single data item
- will exceed 64K, so the choice between large and huge is
- usually easy.
-
- 3 MEMORY MODEL BENCHMARK
-
- The benefits of using the larger pointer types are
- obvious, and amount to a go/no go decision in most cases. For
- those cases where performance and/or space is very critical
- and the choice of memory model may affect the design in
- non-trivial ways, it is good to get an idea ahead of time of
- what the costs are as well. The simple benchmark used here
- was devised for such a project, where the the design could
- take advantage of as much storage as possible, but the
- performance of bitor() and similar functions was critical,
- since they would be called millions of times each.
-
- 3.1 Bench Mark Code
-
- The source code for the very simple bench mark performed
-
-
-
-
-
- Page 11
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- is shown in Listing 2 and Listing 3. Listing 2 defines the
- main() function and Listing 2 defines an external function
- bitor(), which performs a bitwise or operation between two
- memory buffers. The bench mark measures the efficiency of
- calling and executing bitor() under various memory models,
- which was the problem of interest for the project which
- motivated this whole study.
-
- An important reason for compiling the functions
- separately, besides the fact that bitor() was actually
- intended for use in other programs was that it quaranteed that
- no optimizer could could eliminate the repetitive calls.
-
- The main() function accepts parameters which determine how
- many times to call bitor() and the size of the buffers, up to
- a maximum of 256. A two level nested loop was used simply to
- avoid using a long integer counter for more than 64K
- repetitions.
-
- Both functions were optimized for speed. This is the
- default with MSC, and was used with Turbo C for consistency.
- This is usually a wise choice for small programs anyway. In
- this case, the bulk of the code comes from the library
- routines, and the bulk of the execution is in the compiled
- functions. Optimizing the compiled functions for space would
- have saved little space, and possibly cost a lot of time. The
- usual rule should be to optimize anything seldom executed for
- space, and anything frequently executed for time.
-
- 3.2 Execution Time Test
-
- When testing for execution time, I used the Rexx program
- shown in Listing 4 to set up and time the execution of the
- .EXE files prepared under each memory model. In every case,
- the .EXE files are copied to the D: the DOS path and is a RAM
- disk. This virtually eliminates any variability caused by the
- placement of the .EXE files on a hard disk. Two tests are
- performed.
-
- Table 1 shows the time in seconds when bitor() is
- executed 300,000 times specifying a length of 0, thus
- measuring mostly calling overhead. The differences between
- memory models is thus mostly related to the type of code
- pointer.
-
- Table 2 shows the time to execute bitor() 2,500 times
- specifying a length of 256. In that case the execution time
- reflects predominantly the indirect memory references in
- bitor(), which do the real work take most of the time, so the
- primary enfluence is the code pointer type.
-
- The results are not surprising. The small model is the
- most efficient, followed medium or compact, depending upon
- which test you look at, then large, and finally huge.
- Further, in the first test, compact is nearly equal to small
-
-
-
-
-
- Page 12
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- and medium nearly equal to large. In the second this grouping
- is reversed. Medium is close to small and compact is close to
- large. This confirms the analysis done ahead of time. It
- also goes to show again that the relative importance of
- different factors affecting performance depends upon not only
- the specific program, but sometimes the parameters or other
- data as well.
-
- One thing which is surprising at first is that although
- MSC 4.0 and 5.0 are generally quite close, 4.0 shows a (pardon
- the pun) huge penalty for using the huge model in the second
- test. This is probably because the huge model was a new
- feature with that release, and by the time release 5.0 came
- out developers had had more chance to optimize it.
-
- 3.3 Code Size Compared.
-
- Table 3 lists the size of the .OBJ and .EXE files
- produced by each compiler with each memory model. The files
- have been renamed according to their respective memory
- models. The results are mostly self explanatory. The size of
- the .EXE files must be taken with a half a grain of salt,
- since they consist mostly of library routines, which may not
- have even been written in C, and don't necessarily shown the
- quality of the compiler.
-
- 3.4 Conclusions
-
- For each compiler, the time and code space efficiency of
- the various memory models compare to one another exactly as
- our theoretical explanation predicts. That is that the small
- model is the most efficient and should be used in those cases
- where it will serve the purpose. These tests show no
- advantage of the tiny model over the small model.
-
- Medium and compact are both between small and large, but
- can't be strictly ordered. The relative effeciency of these
- two depends upon the individual program and data. In any
- case, the programmer is seldom faced with the choice between
- medium and compact.
-
- The large model is less efficient than small, medium, or
- compact, though the difference between it and either medium or
- compact may not be significant. When far code references
- predominate medium is close to large and compact is close to
- small. When data references predominate the situation is
- reversed. The latter case is the most common in practice.
-
- The huge model is the least efficient. The penalty for
- going from large to huge is quite severe with MSC 4.0, less
- with 5.0, and almost insignificant for Turbo C, a real tribute
- to the optimization of Turbo C.
-
- Caution is always in order when using bench marks to
- compare different vendor's program products, especially
-
-
-
-
-
- Page 13
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- compilers. It is often easy to devise a test to make one's
- choice come out on top. Contradictory advertising claims
- suggest this is in fact what vendors do. The bench mark shown
- here is highly selective, in that it aims to isolate certain
- features of interest. It does not use any floating point
- operations, recursion, or complex calculations of any kind,
- and does not do any significant amount of i/o, for example.
- Still, it does measure the things of interest here rather well
- and was not written with the purpose of proving a given
- compiler better or worse.
-
- It is therefore worth noting, without drawing dogmatic
- conclusions, that, contrary to the claims of Microsoft when
- pushing upgrades to 5.0, version 4.0 sometimes produces better
- object code. In fact, for actual applications, I have hardly
- ever found a case where recompiling something with MSC 5.0
- yielded a smaller or significantly faster .EXE file than I
- previously had gotten from 4.0.
-
- MSC 5.0 introduced a lot of new functions, but if you
- don't need them and are not using the huge model you may do
- better to continue using 4.0. I have also found version 4.0
- to be a much more reliable product. I only report my
- experience. Perhaps my applications are not representative.
- I never use floating point math but use recursion fairly
- often, for example.
-
- So many bugs were reported with 5.0 that Microsoft rather
- quickly announced 5.1. I did not have 5.1 available for test
- because I had such a bad experience with 5.0 that I didn't
- feel like paying another upgrade fee to fix their bugs,
- preferring to spend about the same amount of money for Turbo
- C, if it came to that. The results of this limited bench mark
- seems to strengthen that resolve. In every case, Turbo C
- produced tighter, faster object code, a rather impressive
- achievement considering the price differential.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 14
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- =================================================================
- /* Listing 1: CMDARGS.C */
- /* get unparsed command line arguments from PSP */
- /* sets input variable to the line and returns length */
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #define FP_PTR(seg,off) ((((long)seg)<<16)+off)
-
- int cmdargs(result) char *result;
- {
- unsigned char far *dta=FP_PTR(_psp,0x80);
- /* if compact, large or huge use memcpy */
- #if defined(M_I86LM) || defined(M_I86CM)
- memcpy(result,dta+1,*dta);
- result[*dta]=0;
- return *dta;
- #else
- {
- int length=*dta;
- int ret_len=length;
- while (length--)
- *(result++)=*(dta++);
- *result=0;
- return ret_len;
- }
- #endif
- }
-
- #if defined(TEST)
- #include <stdio.h>
- main()
- {
- char args[128];
- cmdargs(args);
- putchar('"');
- fputs(args,stdout);
- putchar('"');
- }
- #endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 15
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- =================================================================
-
- /* LISTING 2 - TEST.C */
- #include <stdio.h>
- void bitor(char *, char *, int);
- /* Use preprocessor symbols to determine
- content of string model[] */
- static char model[8]=
- #if defined(M_I86SM)
- "small";
- #elif defined(M_I86MM)
- "medium";
- #elif defined(M_I86CM)
- "compact";
- #elif defined(M_I86HM)
- /* NOTE huge must be tested before large,
- because huge sets M_I86LM as well as M_I86HM */
- "huge";
- #elif defined(M_I86LM)
- "large";
- #else
- "unknown"; /* non-standard, (or Turbo C) */
- #endif
- main(argc, argv) int argc; char **argv;
- {
- char buf1[256], buf2[256];
- int i=0, j, jlim=0, len=sizeof(buf1);
- /* i=outer loop count; j=inner loop count; defaults 0 0 */
- switch (argc)
- {
- case 4:
- len=atoi(argv[3]);
- if (len>sizeof(buf1)) len=sizeof(buf1);
- case 3:
- jlim=atoi(argv[2]);
- case 2:
- i=atoi(argv[1]);
- }
- printf("model=%s i=%d j=%d len=%d\n",model,i,jlim,len);
- while (i--)
- for (j=jlim; j; j--)
- bitor(buf1,buf2,len);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 16
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- =================================================================
-
- /* LISTING 3 - BITOR.C */
- /* Perform bitwise or between two buffers */
- void bitor(x,y,len) char *x, *y; int len;
- {while (len--) *(x++)|=*(y++);}
-
- =================================================================
-
- /* Listing 4: TIMETEST.REX */
- source='MSC4 MSC5 TURBOC'
- parms.1=10 30000 0
- parms.2=1 2500 256
- models='S M C L H' /* Tiny model tested separately */
-
- do ii=2 to words(source)
- s=word(source,ii)
- copy '\'s'\*.exe d:'
- outfile=s'.DAT'
- do j=1 to 2
- do i=1 to words(models)
- m=word(models,i)
- /* Here is the key part: Execute and record time */
- call time r
- 'TEST'm parms.j
- time.j.m=time(e)
- end
- end
- do i=1 to words(models)
- m=word(models,i)
- data=m time.1.m time.2.m
- say data
- call lineout outfile, data
- end
- end
- exit
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 17
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- =================================================================
-
- Table 1: Speed Test - Function Calls
-
- Model MSC 4.0 MSC 5.0 Turbo C 1.5
- ------- ------- ------- -----------
- Tiny 25.10
- Small 35.32 34.27 25.10
- Medium 42.13 41.58 27.30
- Compact 35.54 34.43 21.42
- Large 42.29 41.63 23.07
- Huge 43.88 41.63 25.98
-
- =================================================================
-
- Table 2: Speed Test - Indirect Byte Reference
-
- Model MSC 4.0 MSC 5.0 Turbo C 1.5
- ------- ------- ------- -----------
- Tiny 18.89
- Small 32.19 32.19 18.90
- Medium 32.29 32.24 18.95
- Compact 35.92 35.86 30.92
- Large 35.98 35.93 30.98
- Huge 68.88 41.19 31.03
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 18
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- =================================================================
- Table 3 - Comparing .OBJ and .EXE File Size
- MSC MSC Turbo C
- File 4.0 4.0 1.5
- -----------
- bitort.obj * * 194
- bitors.obj 309 287 192
- bitorm.obj 316 294 197
- bitorc.obj 309 285 196
- bitorl.obj 316 292 201
- bitorh.obj 381 326 182
-
- testt.obj * * 473
- tests.obj 541 521 473
- testm.obj 557 537 487
- testc.obj 560 541 495
- testl.obj 576 557 509
- testh.obj 653 636 485
-
- testt.exe * * 6534
- tests.exe 6670 7383 6334
- testm.exe 6870 7531 6476
- testc.exe 8770 9501 7898
- testl.exe 8970 9649 8056
- testh.exe 9082 9729 9143
-
- * Tiny model not applicable to MSC.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 19
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- Public Domain Software Review: ROFF By Barry Lynch
-
- Program: ROFF4.ARC
- Purpose: A MS-DOS implementation of ROFF a UNIX utility.
- Provides document formatting and typsetting.
-
- A friend of mine suggested that I use ROFF to produce C
- News. Previously I had mentioned the hassle involved with
- generating each edition of C News. So, I picked up a copy of
- ROFF4 and tried it out.
-
- This edition of ROFF4 is a 1984 version that was
- originally written by Ernest bergmann of Lehigh University. C
- source code is provided as well as 19 pages of documentation.
- This issue of C News was generated with this package. The
- output is excellent and the utility is fairly easy to use, if
- you read the documentation carefully.
-
- However, there are some problems that need to be
- addressed. One is the documentation. It does not clearly
- spell out the functionality of each option. I had difficulty
- getting certain lines NOT to right justify, even after putting
- a non-right justify flag in place. Also, the src code example
- included with one of the articles was mangled. I had to cut
- and paste a new version of src in.
-
- All in all this is not a bad utility. The problems that
- I experienced could be to my unfamiliarity with ROFF. I will
- be spending the next couple of weeks working with it to make
- sure that it can indeed do the job I need it to do. Which is
- create C News automatically.
-
- * Editor's Note: I will be working on enhanceing this product
- in the coming months. Specifically adding
- on-line help and cleaning up the documentation
- with examples.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 20
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- FILECHK version 1.0 by Arnold Cherdak, all rights reserved
-
- Disk File Integrity Checker: Reads all files on a disk or in
- one or more (sub)directories to verify that the directory
- entry for each file is correct and that the file is readable.
-
- Usage: FILECHK [-D] [-H] [-?] [directoryname]
-
- Default operation (without command line entries) causes
- FILECHK to read all files in the current directory and all files
- in subdirectories below the current directory.
-
- -D option causes FILECHK to process files in the current
- directory,
- only.
-
- -H and -? options provide the help screen (this one).
-
- The presence of a string, 'directoryname', causes FILECHK to
- begin processing in the directory having the name,
- 'directoryname'.
-
-
- This program was written in response to a friend's plea for
- help. He runs several PC networks which have been in
- operation for quite some time. Occasionally, one of his
- installations receives a near hit by lightning. Needless to
- say, this scrambles the computers' brains and creates problems
- which don't show up right away in addition to those that
- announce themselves with furious noises and billows of smoke
- -- surge protectors, notwithstanding.
-
- FILECHK reads all the files on the disk or in a directory or
- a directory and its subdirectories. If the files can be read
- and the size as read agrees with the directory entry, then
- it's a pretty good bet that the file is usable. Friend had
- several cases where directories were OK and the files had been
- clobbered and effects on network operation weren't readily
- discernable all the time. After much searching among HUNDREDS
- of files, he finally found the few bad files. FILECHK will
- now do it for him faster and more completely than he can do
- it.
-
- If you want a record of FILECHK's output, you may redirect
- it to your printer or to a file using the normal DOS
- redirection since all output goes to stdout. Example:
- FILECHK -d
- or FILECHK -D utilities >prn
-
- I've included the source code in Turbo C, version 1.5. I
- began to do this since the virus problem became so acute.
- With the source, you can compile the program yourself and be
- certain that there will be no surprises in store for you when
-
-
-
-
-
-
- Page 21
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- you run it. I've run FILECHK in the root directory of my 30
- megabyte drive in my own computer. It read over 25 megabytes,
- about 1600 files in a veritable rat's nest of subdirectories
- in about 5 minutes. It would be a bit faster when writing to
- a file, a bit slower when writing to the printer. FILECHK
- found no problems. I ran CHKDSK to compare and it found 3
- lost clusters. In the past, I've found that lost clusters
- don't always mean that the files are lost. In fact, I've been
- able to make the lost clusters disappear by moving files off
- or around the disk. The files copied all right and
- afterwards, CHKDSK could find nothing wrong. Stranger than
- fiction.
- Arnie Cherdak
- 8/14/88
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 22
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- ARTICLE SUBMISSION STANDARDS AND ADDRESSES
-
-
- As I have repeatedly stated in this newsletter and
- previous issues, I would like to see user-submitted articles,
- reviews or questions. Listed below are the standards that
- should be followed to make my job easier as an editor.
-
-
- - Articles should be submitted in a ASCII non-formatted
- file. (Margins 0-65 PLEASE)
-
- - If the article include code fragments as examples. Then
- you can include the entire source file if you like for
- inclusion with the newsletter.
-
- - Book or magazine reviews should follow the same format,
- that is outlined in this issue. The publisher, author,
- title, and ISBN number are a must.
-
- - Compiler/and or product reviews, should include the
- version number and manufacture. If possible, reviews
- should include a sample program with benchmarks.
-
-
- If you have any questions you can contact me at the
- address's included on the next page.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 23
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- ADDRESSES
-
- The C BBS is located at:
-
- C BBS
- % BCL Limited
- P.O. Box 9162
- McLean VA, 22102
-
-
- or you can send netmail to:
-
-
- 1:109/713
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 24
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
-
- INDEX
-
- Subject: Issue:
-
- Articles:
-
- Additional Comments of Filename Wild.. 6
- Beginning C Functions 7
- C Spot Run: A User Supported Library 7
- Database Design in C 10
- Filechk 11
- Filename Wildcard Expansion in MSC 4
- Integrated Environment: TC & QC 5
- Memory Models 11
- Programming the Hercules Graphics Card 8
- Programming the Hercules Graphics Card: Part 2 9
- Talking with a Fossil 5
- TurboC and Interrupts: A few Questions 2
-
- Book Reviews:
-
- C Chest: and other treasures. 6
- C Database Development 1
- C Programming Guide 1
- C Programming Language 1
- C Programmer's Guide to Serial Communications 3
- C Programmer's Library 1
- C Primer Plus 1
- C the Complete Reference 2
- Crafting C Tools for the IBM PC 2
- Learning to Program in C 1
- Microsoft C Programming on the IBM PC 1
- MS-DOS Developer's Guide 4
- Programming in Windows 3
- QuickC Programming for the IBM 10
- Reliable Data Structures in C 1
- TurboC: Memory Resident Utilities 5
- TurboC Programmer's Reference Book 2
-
-
- Compilers:
-
- QuickC 1
-
- Software Reviews:
-
- Bplus11.arc 3
- C_Dates.arc 4
- Cdate.arc 4
- Casm.arc 3
- C-subr.arc 4
- Docu.arc 3
- Ezwind.arc 8
- Jcl-src.arc 4
-
-
-
-
-
- Page 25
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
- Mscpopup.arc 3
- Ndmake41.arc 4
- Nuc-subr.arc 3
- Prndoc.arc 6
- Sed.arc 6
- Shift_c.arc 4
- Sysact11.arc 4
- Tp_to_qc.arc 3
- Xenixarc.arc 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 26
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
- DISTRIBUTION POINTS
-
-
- Board Name Number Net/Node Sysop
-
- United States
-
- C BBS (703) 644-6478 1:109/713 Barry Lynch
- Burke, VA
-
- Jaz C-Scape (904) 724-1377 1:112/1027 Tom Evans
- Jacksonville, FL
-
-
- Eastern C Board (201) 247-6748 1:107/335 Todd Lehr
-
- OTHER BOARDS THAT CARRY C NEWS:
-
- Exec-PC (414) 964-5160 .. Bob Mahoney
- Milwaukee, WI
-
- TAMIAMI (813) 793-2392 Gerhard Barth
- Naples, FL
-
- Sound of Music (516) 536-8723(2400) Paul Waldinger
- (516) 536-6819(9600 Hayes V)
-
- Canada
-
- Another BBS System (416) 465-7752 1:148/208 Mark Bowman
- Toronto, Canada
-
- Europe
-
- Fido_N1_1 31-8350-37156 2:500/1 Henk Wevers
-
- The Netherlands
-
- Australia
-
- Sentry BBS 02-428-4687 ... Trev Roydhouse
- (300-2400) Non-Mail Times
- (300-19,200) Mail Hour (Trailblazer)
-
- The Sentry BBS replaces Alpha-Centuri that has been down for
- awhile.
-
-
-
-
-
-
-
-
-
-
-
- Page 27
-
- C News Vol. 1 Issue 11 Sept 15, 1988
-
- USER RESPONSE FORM
-
- This form will be included as a regular feature in all future
- issues of C NEWS.
-
-
-
- What did you think of the content of this Issue? _____________
-
- _______________________________________________________________
-
- What improvements can you think of that would make C News a
- better tool for the C Community?
-
- _______________________________________________________________
-
- _______________________________________________________________
-
-
- What is your favorite section or sections? ___________________
-
- _______________________________________________________________
-
-
- What don't you like about C News? ____________________________
-
- _______________________________________________________________
-
-
- Additional Comments: _________________________________________
-
- _______________________________________________________________
-
- _______________________________________________________________
-
- _______________________________________________________________
-
-
- Page 28
-
-
-
-