www.digitalmars.com         C & C++   DMDScript  

c++ - loop optimization and farmalloc(64KB)

reply Christopher Ventura <Christopher_member pathlink.com> writes:
Hi there.  I am upgrading my compiler (BC++ 3.1 and BC5.5) for the purpose of
doing Win32 development with debugging support.  (I can afford whatever from the
Big Guys, but I prefer to support independent developers.)

I am evaluating your product by compiling a suite under each, and looking at the
differences.  I found two behavioral differences that may be the result of
"improvement opportunities" in the DigitalMars product.

I believe that I am correct about the first one.  The second one may be an RTFM
issue, but I am really sure that I am right.  They are presented below.

Please take a look at these two issues.  Thank you.

ps.  Oh yeah, you're that guy.  I did a Data I/O Boardsite custom adaptor at my
Day Job last summer (fall?).  We have some 20 base units around the world, and
about 4x that many adaptors.  We have coated boards with soldered EPROMs
('512s), which may be from different manufacturers.  Anyway, a couple of lines
of code and interface for independently programming the devices.

Combine variable lifetime analysis and loop-reduction optimizations.

It appears that a variable's per-iteration dependency is not identified when it
is passed to a function.

The following code creates a string of capital letters.  When the variable is
not used afterward, the loop is optimized to execute just the last iteration.
When using the variable afterward, the optimization is not performed.  The
variable is passed to a function with a different value every time.  I
demonstrate this by showing that only the last iteration is called.

//DM 8.27 optimization demonstrator
//build using "sc -o optimize.cpp" (optimizations on)

#include <stdio.h>

//does not work with the "-o" option
//create a string of successive capital letters
void string_NOGOOD(int n,char string[])
for (int i=0;i<n;++i)

//works regardless of the "-o" option
//create a string of successive capital letters
void string_OKAY(int n,char string[])
for (int i=0;i<n;++i)

*string=0; //fake out the optimizer

char s[50];


string_OKAY  (10,s);

return 0;

Output is:

Expected both lines to be the same.

Allocate >64K in a large-data DOS memory model.

It appears that only the low 16 bits of the 32-bit size are used when computing
the number of paragraphs to allocate.  That is, it looks like malloc() uses
"unsigned paragraphs=((unsigned)(bytes+15L+overhead))>>4;" rather than "unsigned

I am pretty sure that farmalloc(unsigned long) should allocate more than 64KB.
The type of its formal parameter, which can hold a 20-bit number, implies such.
I read the webpage and header file, and did not find any mention of only <64KB.

The following code allocates 130Kb for int* j, but the heap grows (shrinks?) by
only 2Kb.  I demonstrate this by showing the pointer aliasing, with j[1032] and
k[0] sharing the same location.

//DM 8.27 large-data malloc() demonstrator
//build using "sc -mc optimize.cpp" (compact memory model)

#include <dos.h>
#include <malloc.h>
#include <stdio.h>

//from DOS.h:  void __far * __cdecl farmalloc(unsigned long size);

//does not work with the "-mc" option
//allocate memory
int* i=farmalloc( 1 *1024*sizeof(int));
int* j=farmalloc(65 *1024*sizeof(int));
int* k=farmalloc( 1 *1024*sizeof(int));
printf("i=%08lX j=%08lX k=%08lX\n",(long)i,(long)j,(long)k);

printf("bytes of j = %d\n",((long)k-(long)j)>>12);


//initialize an element in k[]

//set an element of j[], and note the effect on k[].

return 0;

Output is:
i=150D0000 j=158E0000 k=160F0000
bytes of j = 2064

Expected ~130KB allocated, and no aliasing.
Apr 20 2002
parent "Walter" <walter digitalmars.com> writes:
I'll check into them. Thanks. -Walter
Apr 20 2002