- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I'm trying to write some code to determine how much memory is available on the machine, such that processing doesn't start when there's not enough memory to finish the problem. My understanding is that there is no native Fortran command to determine this, correct?
I've hacked together the following, which progressively allocates more and more memory, until it finds the limit:
program mem_test
implicit none
real, dimension(:,:,:), allocatable :: MX
integer :: err_alloc,ng
NG = 1700
DO WHILE (.NOT.ALLOCATED(MX))
IF (.NOT.ALLOCATED(MX)) ALLOCATE (MX(1:NG,1:NG,1:NG), STAT = ERR_ALLOC)
IF (ERR_ALLOC == 0) THEN
NG = NG + 5
DEALLOCATE(MX)
ELSE IF(ERR_ALLOC /= 0) THEN
WRITE (*,*) "STOPPING AT NG=",NG, " WITH ERROR=",ERR_ALLOC
EXIT
ENDIF
END DO
WRITE (*,*) 'ALLOCATED ', 4.0 * (NG**3) / 1000000.0, ' MEGABYTES.'
end program
I'm running this on a quad-core Xeon workstation with 16 GB of memory. See below:
849 fischega@lxlog01[~/testdir/memtest]> free -m
total used free shared buffers cached
Mem: 16054 3852 12201 0 116 3158
-/+ buffers/cache: 578 15476
Swap: 8236 0 8236
850 fischega@lxlog01[~/testdir/memtest]> uname -a
Linux lxlog01 2.6.16.60-0.21-smp #1 SMP Tue May 6 12:41:02 UTC 2008 x86_64 x86_64 x86_64 GNU/Linux
I seem to be hitting a limit around 7 GB, whereas "free" claims there is 12 GB available. What gives? Is my math wrong? 4 bytes for a vanilla REAL, right?
Thanks,
Greg
- Marcas:
- Intel® Fortran Compiler
Link copiado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I think that maximum memory is limited by the OS and not by the compiler.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Thanks.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
You may want to see if strace provides any useful information. You can also try it with malloc and free in place of ALLOCATE (remembering to get the number of bytes right.)
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Greg,
I am not a Linux programmer so my comment may be for naught.
The 7GB appears to be approximately 1/2 the available memory.
Linux is structured to grow the application stack down from the negative address space (-8, -16, ...) or(-4, -8, ...) depending on x64 or x32.
My guess is without specifying how large of stack space to reserve Linux may assume 50/50 for stack and allocatables.
Try specifying a 1GB stack limit and see if you go above the 7GB. (You will have to read the docs as to how to go about specifying stack limit.)
Jim Dempsey
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I tried the following variant on a Linux (SLES10) system with 16 GB of physical memory and approximately 8GB of swap space. This seemed to successfully allocate all the memory available, and not more. The stack is not involved here. Note that you need -i8 or a source code change in orderto computeNG**3, else you may get an integeroverflow close to 8 GB (4.0 * 1250**3). You need to access the array after allocating it - you can allocate as much memory as you like, if it is never used.
program mem_test
implicit none
real, dimension(:,:,:), allocatable :: MX
integer :: ng, err_alloc, i
NG = NG3
ALLOCATE (MX(1:NG,1:NG,1:NG), STAT = ERR_ALLOC)
DO I=1,NG,NG/10
WRITE(*,*) MX(I,I,I)
ENDDO
WRITE (*,*)
WRITE (*,*) 'ALLOCATED ', 4.0 * (NG**3) / 1000000.0, ' MEGABYTES.'
end program
ifort -fpp -i8 alloc2.f90 -DNG3=1800;./a.out
.....
ALLOCATED 23328.00 MEGABYTES.
ifort -fpp -i8 alloc2.f90 -DNG3=1850;./a.out
forrtl: severe (174): SIGSEGV, segmentation fault occurred
____________________________________________
In addition, you could call the library function SYSTEM (or SYSTEMQQ) to execute the shell command free -m:
use ifport
IERR=SYSTEM("free -m")
and either parse and redirect the output to a file,so that you can read it back, ortry something more clever. You could even use SYSTEM to run repeatedly a test program like the one above, gradually increasing the memory allocation until it failed, and SYSTEM returns a non-zero error code.
You can find a description of SYSTEM and SYSTEMQQ in the main Fortran compiler documentation.

- Subscrever fonte RSS
- Marcar tópico como novo
- Marcar tópico como lido
- Flutuar este Tópico para o utilizador atual
- Marcador
- Subscrever
- Página amigável para impressora