Article 62352 of comp.os.vms:
Path: jac.zko.dec.com!pa.dec.com!news1.digital.com!uunet!usc!howland.reston.ans.net!swrinde!ihnp4.ucsd.edu!mvb.saic.com!info-vax
From: Jerry Leichter <leichter@lrw.com>
Newsgroups: comp.os.vms
Subject: RE: FORTRAN oddity
Message-ID: <9506060230.AA03586@uu3.psi.com>
Date: Mon,  5 Jun 95 22:15:29 EDT
Organization: Info-Vax<==>Comp.Os.Vms Gateway
X-Gateway-Source-Info: Mailing List
Lines: 78

	I'm posting this for some of our astro guys here who have asked me to
	look into an anomaly they are experiencing trying to compile and link
	a rather large FORTRAN program. Without going into too much detail the
	symptom is as follows:

	They added an additional file containing a single subroutine to the
	entire program. Their make.com is simply a matter of compiling each of
	the several files containing source subroutine(s), followed by a link
	of the main program and all of the subroutines it references. They are
	making no exotic calls beyond that as these guys are in the business
	of flying satellites and not VMS programmers. 

	They've noticed that the addition of this one subroutine has caused
	the .exe size to go from something like 6000 blocks to 24000 blocks.
	I suggested moving the  position of the subroutine in the linking
	sequence to the top of the routines listed in their link command and
	lo and behold the size comes back down to about 6000 blocks !

	The subroutine in question passes nearly all of it's arrays (some
	multi- dimensional and most real*8) as calling args with very few
	arrays in the common blocks.

	I'm not looking for anything in horrendous detail but wondered if
	anyone could comment on the behaviour as I've not seen it before.
	Since we've evidentally overcome the "problem" it might be useful to
	know how it arose in the first place so as to avoid it the next time
	-- if possible.

What you are almost certainly seeing is demand-zero compression - or, more
precisely, the lack thereof.

Uninitialized static data, such as large commons, are actually initialized to
all zeroes.  Normally, the Linker doesn't actually store explicit zeroes in
the EXE file; it instead leaves an indication in the file that so many zero-
filled pages are to be allocated at this point.  The pages are allocated and
zeroed at run time.  (In fact, they aren't actually allocated or filled until
the program touches them - the first page fault against such a page causes
the allocation and zeroing to be done.  Hence, these are called "demand-zero"
pages.)

An EXE files is organized as a set of sections.  Adjacent sections in the
file normally have different attributes - you won't normally see two adjacent
"demand zero" sections (sections consisting of demand-zero pages), because
the Linker will notice that and combine them.  However, if you have a demand-
zero section, then some initialized data (which requires a different kind of
section), then another demand-zero section, the two remain separate.  Thus,
depending on the exact ordering of things being linked together, the total
number of different sections may change.

Now, this wouldn't make any difference except that the Linker imposes a limit
on the total number of sections it is willing to create in an image.  When
this limit is reached, the Linker stops looking for regions of memory to
turn into demand-zero sections; it just leaves big runs of zeros in the EXE
file.

The limit the Linker uses can be changed using a Linker option, ISD_MAX.
The default limit is approximately 96 - approximate because there are some
interactions with the kinds of sections in the EXE.  To increase the limit,
create a file, say ISD.OPT, containing a line like:

ISD_MAX=125

Then, on your LINK line, add ISD/OPTIONS - .OPT is the default type for an
options file.  Your EXE file should now stay at its smaller size, at least
until the astro guys grow it a whole lot more!

There are costs involved (mainly in much-lengthened startup time when you RUN
the program) in having very large numbers of sections, so don't just increase
ISD_MAX without limit.  If you find that no reasonable value of ISD_MAX works
for very long, you'll need to look at the CLUSTER and COLLECT Linker options,
which allow you to alter the order in which things appear in memory.  This
way, you can move all the parts that are destined to be zeroed into one big
section that will be demand-zero.  For large, frequently-executed programs,
this kind of manipulation can be a significant (if tricky - you have to become
really familiar with the Linker to do it) optimization.  For most programs,
it's not worth the effort.  You'll have to judge what's appropriate in your
case.
							-- Jerry


