www.digitalmars.com Home | Search | C & C++ | D | DMDScript | News Groups | index | prev | next
Archives

D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger

C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows

digitalmars.empire
digitalmars.DMDScript

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

↑ ↓ ← 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.

//optimize.cpp
//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)
string+=sprintf(string,"%c",'A'+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+=sprintf(string,"%c",'A'+i);

*string=0; //fake out the optimizer
}

main()
{
char s[50];

string_NOGOOD(10,s);
puts(s);

string_OKAY  (10,s);
puts(s);

return 0;
}


Output is:
J
ABCDEFGHIJ

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
paragraphs=(unsigned)((bytes+15L+overhead)>>4);".

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.

//malloc.cpp
//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
main()
{
//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[]
k[0]=0;
printf("%d\n",k[0]);

//set an element of j[], and note the effect on k[].
j[0x810/sizeof(int)]=1;
printf("%d\n",k[0]);

return 0;
}

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

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