- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a large piece of code which includes a derived type definition of the following form
Type :: Stuff
Type(Particle) :: Particles(MaxParticles)
Other stuff, including more arrays of derived types
End Type Stuff
Particle is about 50 32-bit words in size and MaxParticles is a few million.
I want to make Particles allocatable by replacing it with a pointer (the aim being to be able to alter maxparticles without re-compiling). However when I do this the exe file size increases from about 20MB to about 400MB and runs slower. Compilation options are the defaults used by the development environment wizard for quick win applications (apart from an increase in stack size). Note the size variable in the allocate is read in, so the compiler cannot know its size.
This is all with Compaq Fortran 6.6.0.
I'd be interested if anyone else has had similar problems or found solutions.
Of course I should try to reproduce the issue in a smaller program, but I thought I'd see if anyone else had had similar experiences first.
Many thanks for any help.
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did you add an initialization of the pointer field? Initialized data gets explicitly represented in the object file, whereas uninitialized data does not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Many thanks - problem solved, although I don't really understand how!
I had initialised it to null like this:
Type :: Stuff
Type(Particle), Pointer :: Particles(:) => Null()
...
End Type
(I need to test if its associated, because I may want to deallocate and reallocate to a different size, hence I wanted to start with a well defined state.)
I've now changedto putting Stuff%Particle => Null() in the executable statements rather than in the declaration and this solves the problem (run time as well as exe file size).
However I would have thought that even if it was in the object file it would then be very small (cos of the '=>Null()'). How does the compiler know how much space it may need to allow in the object file?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On Windows, there are two kinds of data sections, one for initialized data and one for uninitialized data. Uninitialized data sections are represented in the EXE only by a starting address and length, letting the image activator create the address space. Initialized data has every byte represented, and gets loaded directly.
Unfortunately, if you have a large variable where only one bit of it is initialized, that effectively makes the whole thing initialized. Unlike some operating systems I have used, Windows does not have the ability to represent large chunks of zero-initialized storage in a compact manner.
Unfortunately, if you have a large variable where only one bit of it is initialized, that effectively makes the whole thing initialized. Unlike some operating systems I have used, Windows does not have the ability to represent large chunks of zero-initialized storage in a compact manner.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But I don't see how the modification of the code from static arrays to pointers/allocatables could cause the growth??? I'd expect exactly the opposite, as with dynamic arrays there's (almost) no initialization info to store. There must be something else to the problem, in my opinion.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It didn't. It was the adding of the =>NULL() initialization to the pointer elements that did it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ahi get it now. I thought that the Stuff was also a dynamically allocated array, which it apparently isn't. If there is a static type(Stuff):: stuffs(MANY), the exe size problem will indeed occur if MANY is, well, many.
As a workaround, making everything dynamically allocated (both the TYPEs themselves and their POINTER components) will solve the problem with exe size regardless of initialization. I'm not sure about ratios of execution speed, but I wouldn't expect a radical difference between
* static allocation/initialized components
* dynamic allocation/initialized components.
In the first case, the loader (image activator) will do the initialization before the image startup as Steve described; in the second case, the initialization will occur in run-time, during allocation (ALLOCATE will do the it internally).
Of course, leaving things uninitialized will be faster still (regardless of static/dynamic allocation), but that approach makes me a bit scary -- for example, you cannot reliably test whether an uninitialized pointer is ASSOCIATED.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In fact "Stuff" was a scalar, but the "other stuff" inside Stuff was quite large and became included in the exe file.
The run time change was probably just a consequence of the longer load time - I didn't test it on a long run where it may have been insignificant.
Its slightly more trouble to have an initialisation routine which does the => Null, but not much.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page