gfortran version: GNU Fortran (GCC) 4.3.0 20070810 (experimental)
OS: Intel OS X 10.5.2
Processor: 2.16 GHz Intel Core 2 Duo
"gFortran executable size" depends on how gfortran is built. It could be
small, and could be huge as you experienced. It totally depends on where you
download the compiler. If you are on Windows, you can download gfortran and
c++ at www.Equation.com. The compiler built by Equation.com will produce a
small-sized executable.
As compared to ifort, gFortran may produce a smaller executable. I post an
example in the following
04/26/08 04:01p 293,376 bench1_gfortran.exe
04/25/08 07:14a 667,648 bench1_intel.exe
Both EXEs are from the same source code, and static link. It can be seen
gfortran produces a smaller executable in this example. ifort has a better
optimization. For example, EXE from gfortran takes 105 seconds on one
processor, and EXE from ifort can finish it about 51 seconds (on a baby 200
MHZ dual pentium pro). The EXEs have classic pentium instructions. In this
example, ifort shows 2X faster. (On some applications, ifort can be up to
6X)
**** EXE by gfortran ****
C:\TEMP>bench1_gfortran
number of equations: 2000000
Half bandwidth: 8
Processor: 1
Elapsed Time (Seconds): 105.05
CPU Time in User Mode (Seconds): 104.05
CPU Time in Kernel Mode (Seconds): 1.00
Total CPU Time (Seconds): 105.05
Processors: 2
Elapsed Time (Seconds): 52.55
CPU Time in User Mode (Seconds): 104.19
CPU Time in Kernel Mode (Seconds): 0.89
Total CPU Time (Seconds): 105.08
*** EXE by ifot ***
C:\TEMP>bench1_intel
number of equations: 2000000
Half bandwidth: 8
Processor: 1
Elapsed Time (Seconds): 51.51
CPU Time in User Mode (Seconds): 50.42
CPU Time in Kernel Mode (Seconds): 1.09
Total CPU Time (Seconds): 51.52
Processors: 2
Elapsed Time (Seconds): 26.28
CPU Time in User Mode (Seconds): 51.80
CPU Time in Kernel Mode (Seconds): 0.69
Total CPU Time (Seconds): 52.48
The only case I know of gfortran creating unreasonably huge executables
(with very long compile and link times) is when you have a very large,
static, parameter array. Show us the code and we'll see.
--
FX
Indeed, the code contains large static executables (not dynamically
allocated). When I comment these out, the object file is a normal
size. Suggestions on avoiding this problem?
-large static arrays-
> Indeed, the code contains large static executables (not dynamically
> allocated). When I comment these out, the object file is a normal
> size. Suggestions on avoiding this problem?
If you really need them, there is nothing else you can do.
Otherwise, if you have something similar to:
DATA X/1000000*123/
or
integer :: x(1000000)=123
print *,x(1)
end
to initialize a large array, instead use
integer x(1000000)
X=123
(It seems that g95 generates a small .o file for zero initialization,
but large for 123.)
-- glen
logical(kind=onebyte) ::
InContactRR(NMOL,NMOL)
logical(kind=onebyte) ::
CheckedRR(NMOL,NMOL)
where NMOL is a large number. It does not seem that the array is
initialized at compile time. These arrays are defined within a module.
The following module is a greatly reduced form of what I'm compiling
(no literals in the original):
------
module Particles
implicit none
logical , dimension(10000,10000) :: InContactRR
logical , dimension(10000,10000) :: CheckedRR
end module Particles
------
It also has a large .o file.
The best solution to the above is to change the static arrays
to dynamic ones:
module Particles
implicit none
logical , dimension(:,:), allocatable :: InContactRR
logical , dimension(:,:), allocatable :: CheckedRR
end module Particles
Then down in your main program, use ALLOCATE to set the size
of the arrays to what you really need:
program main
use Particles
implicit none
...
allocate (InContactRR(1234,1234))
allocate (CheckedRR(1234,1234))
W.
> logical(kind=onebyte) ::
> InContactRR(NMOL,NMOL)
> logical(kind=onebyte) ::
> CheckedRR(NMOL,NMOL)
If they are not initialized it is unusual for them to take up
large amounts of space in the object file. For g95, it seems
that even initialized to zero they don't take up space.
If you are not initializing them I would report a compiler bug.
(Having the SAVE attribute might be enough, though.)
-- glen
Strange. I tried this:
$ cat large.f90
module Particles
implicit none
logical , dimension(10000,10000) :: InContactRR
logical , dimension(10000,10000) :: CheckedRR
end module Particles
$ gfortran -c large.f90
$ ls -sh large.o
4.0K large.o
As you might expect, the .bss is very large
$ readelf -S large.o
There are 9 section headers, starting at offset 0xb4:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 4
[ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 4
[ 3] .bss NOBITS 00000000 000040 2faf0800 00 WA 0 0 32
[ 4] .comment PROGBITS 00000000 000040 00002e 00 0 0 1
[ 5] .note.GNU-stack PROGBITS 00000000 00006e 000000 00 0 0 1
[ 6] .shstrtab STRTAB 00000000 00006e 000045 00 0 0 1
[ 7] .symtab SYMTAB 00000000 00021c 000090 10 8 7 4
[ 8] .strtab STRTAB 00000000 0002ac 00003b 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
The size 2faf0800 is 800000000 (8e+8) bytes, you have two arrays of
10000 x 10000 logicals, or 2e+8 logicals, so four bytes per logical.
You're right, ifort does something different:
$ ifort -c large.f90
$ ls -sh large.o
4.0K large.o
$ readelf -S large.o
There are 5 section headers, starting at offset 0x138:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .strtab STRTAB 00000000 000034 00006f 00 0 0 1
[ 2] .symtab SYMTAB 00000000 0000a3 000090 10 1 6 4
[ 3] .text PROGBITS 00000000 000133 000004 00 AX 0 0 4
[ 4] .note.GNU-stack NOTE 00000000 000137 000000 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
I'm not clear on where ifort is going to put your LOGICAL arrays, but
they are still in the .bss when you link an executable:
$ cat test.f90
program test
use particles
InContactRR(1,1) = .true.
print *, CheckedRR(10,10)
end program test
$ ifort test.f90 large.o
$ readelf -S a.out
There are 30 section headers, starting at offset 0x64658:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 08048134 000134 000013 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 08048148 000148 000020 00 A 0 0 4
[ 3] .hash HASH 08048168 000168 00034c 04 A 4 0 4
[ 4] .dynsym DYNSYM 080484b4 0004b4 000700 10 A 5 1 4
[ 5] .dynstr STRTAB 08048bb4 000bb4 000540 00 A 0 0 1
[ 6] .gnu.version VERSYM 080490f4 0010f4 0000e0 02 A 4 0 2
[ 7] .gnu.version_r VERNEED 080491d4 0011d4 000060 00 A 5 2 4
[ 8] .rel.dyn REL 08049234 001234 000108 08 A 4 0 4
[ 9] .rel.plt REL 0804933c 00133c 000258 08 A 4 11 4
[10] .init PROGBITS 08049594 001594 000017 00 AX 0 0 4
[11] .plt PROGBITS 080495ac 0015ac 0004c0 04 AX 0 0 4
[12] .text PROGBITS 08049a70 001a70 052518 00 AX 0 0 16
[13] .fini PROGBITS 0809bf88 053f88 00001c 00 AX 0 0 4
[14] .rodata PROGBITS 0809bfc0 053fc0 00c610 00 A 0 0 32
[15] .eh_frame_hdr PROGBITS 080a85d0 0605d0 00001c 00 A 0 0 4
[16] .eh_frame PROGBITS 080a85ec 0605ec 000058 00 A 0 0 4
[17] .ctors PROGBITS 080a9644 060644 000008 00 WA 0 0 4
[18] .dtors PROGBITS 080a964c 06064c 000008 00 WA 0 0 4
[19] .jcr PROGBITS 080a9654 060654 000004 00 WA 0 0 4
[20] .dynamic DYNAMIC 080a9658 060658 0000e0 08 WA 5 0 4
[21] .got PROGBITS 080a9738 060738 000078 04 WA 0 0 4
[22] .got.plt PROGBITS 080a97b0 0607b0 000138 04 WA 0 0 4
[23] .data PROGBITS 080a9900 060900 002ba0 00 WA 0 0 32
[24] .data1 PROGBITS 080ac4a0 0634a0 000f60 00 WA 0 0 32
[25] .bss NOBITS 080ad400 064400 2faf4844 00 WA 0 0 32
[26] .comment PROGBITS 00000000 064400 00016b 00 0 0 1
[27] .shstrtab STRTAB 00000000 06456b 0000ec 00 0 0 1
[28] .symtab SYMTAB 00000000 064b08 009da0 10 29 2029 4
[29] .strtab STRTAB 00000000 06e8a8 0061c6 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Note the .bss section (number [25] above) is 2faf4844 (800016452)
bytes, so your logical arrays are still in the same section.
It looks like ifort is putting a description of the logical arrays in
the .mod file, but not putting a .bss section in the .o file, even
though the .bss winds up in the final executable (as it must). (I
don't know how this works, since I thought ifort used the system ld.)
gfortran puts the description of the logical arrays in the .mod file
and puts the ELF section in the .o file.
gfortran seems more honest.
Chip
--
Charles M. "Chip" Coldwell
"Turn on, log in, tune out"
GPG Key ID: 852E052F
GPG Key Fingerprint: 77E5 2B51 4907 F08A 7E92 DE80 AFA9 9A8F 852E 052F
> Indeed, the code contains large static executables (not dynamically
> allocated). When I comment these out, the object file is a normal
> size. Suggestions on avoiding this problem?
Q. Doctor, it hurts when I do this. What is the soution?
A. Don't do that.
I.E. Don't use large statically allocated arrays. Many compilers have
problems with them. This certainly isn't unique to GFortran. I have seen
large (for the time) server systems crash because of this (the compiler
ran the system out of disk space trying to compile the thing). Instead
of having to worry about each new compiler your code is tried on, I
suggest just "fixing" the code. I quote the "fixing" because the code
isn't nonstandard or anything like that; it is just prone to
overstressing compilers. Make the arrays dynamic (as I see Walter also
siggested, but I wanted to support and emphasize the suggestion).
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
Perhaps a better solution is to ask why the OP needs such large arrays
in the first place. 2e8 array elements is huge, even when each is only
one byte. Logicals take only two values so one obvious way is to
simulate a bitmap on integer variables using pre-defined masks.
Looking at the variable names suggests that the run time of the
program may be astronomical too. In particular having flags named
InContact and Checked makes me wonder if some other data structure or
a different algorithm is indicated. Perhaps the problem can be broken
into smaller pieces, etc.
[When I was young we had only 4k of CORE and it still ran FOCAL. :-)]
-- e
> [When I was young we had only 4k of CORE and it still ran FOCAL. :-)]
Hah! I'm still young and only in my first 100, but the very very first
trial 1401 had 1400 bytes before going to 4K and I used the 132-byte
printer area for an overlaying tape operating system.
I don't get it. 2e8 array (even single prevision) takes 800 Mbytes. The
original post states his executable having 700Mbytes.