forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

3gb switch update ?
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8320
Location: Salford, UK

PostPosted: Fri Sep 26, 2008 4:47 pm    Post subject: Reply with quote

Hi John

We have considered the questions that you raise and suggest that the best way forward would be for you to send us a small program/project that illustrates the problems that you are encountering.

In the mean time here is a sample program that allocates about 2.8 GB on my machine
Code:
real(2),pointer::gib(:)
real(1) size
size=0.0
do
  allocate(gib(10000000))
  size = size+80000000
  print*, size
enddo
end


Regards

Paul
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Fri Sep 26, 2008 11:54 pm    Post subject: Reply with quote

Paul,

I emailed you the file big_new_memory.zip on 16 Sep to your hotmail account, which was the account you had previously advised for emailing sample programs. It is a small program with little code, but big arrays. It's a bit of a mess as there is a bit of commented out code, as I tried different ideas.
My example used explicit array sizeing with common or modules. After 1.85 gb of arrays, the executable generated gives "is not a valid Win32 application" error ?

I will try your example, using allocate. My big memory PC is at work.
What pool of memory does allocate get the big chunks of memory from ?

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8320
Location: Salford, UK

PostPosted: Sat Sep 27, 2008 7:50 am    Post subject: Reply with quote

ALLOCATE ends up using the Windows API GlobalAlloc or HeapAlloc.

We will look at your sample code as soon as we can.

Paul
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Mon Sep 29, 2008 12:38 am    Post subject: Reply with quote

Paul,

I tried the allocate approach with real*8 arrays and it failed after 1.15gb.
the following is the commands I used to run it.

ftn95 big_alloc /lis /xref
slink big_alloc.obj /3gb /map:big_alloc.map /file:big_alloc.exe

Code:

!     Last change:  JDC  29 Sep 2008   9:00 am
!  Program to test memory sizes
!
      module large_array
!
      real*10,   parameter :: one   = 1
      real*10,   parameter :: two   = 2
      real*10,   parameter :: eight = 8
!
      integer*4, parameter :: megabyte = 1024*1024/8
!
!   Did not work if declared in module
!      integer*4 array_a_size
!      real*8,    dimension(:), allocatable :: a8_array
!
      end module large_array

      use large_array
!
      integer*4 array_a_size
      real*8,    dimension(:), allocatable :: a8_array
!
      integer*4 i, m_100, m, ii
      real*10   s1, s2, sa
      character description*80
!
      open (unit=98, file='big_array.log', position='append')
!
      call date_time_label (98)
!
      do ii = 1000,2500,50
!
         array_a_size = ii * megabyte
         sa = dble (array_a_size) * 8. / 1024./1024./1024.
         write (description,1000) 'This test for 1 allocated array, memory allocated = ',sa,' gb'
         call report (description)
!
         allocate (a8_array(array_a_size))
         call report (' array a allocated')
!
         write (description,1001) 'initialising array A of ', array_a_size,' real*8 variables'
         call report (description)
!
         m_100 = (1024*1024/8)*100
         m = m_100
         do i = 1,array_a_size
            m = m-1
            if (m <= 0) then
               s1 = dble(i) * eight / dble(1024)**3
               write (description, 1004) s1
               call report (description)
               m = m_100
            end if
            a8_array(i) = i
         end do
         call report ('  array a initialised')
!
         sa = array_a_size
         sa = sa*(sa+one)/two
!
         s1 = 0
         do i = 1,array_a_size
            s1 = s1 + a8_array(i)
         end do
         write (description,1002) '  do Sum of array a = ',s1, s1-sa
         call report (description)
!
         s2 = sum (a8_array)
         write (description,1002) '  Sum of array a    = ',s2, s2-sa
         call report (description)
!
         deallocate (a8_array)
         call report ('  array a deallocated')
      end do
!
1000  format (a,f0.3,a)
1001  format (a,b'zzz,zzz,zz#',a)
1002  format (a,es22.15,' (error=',es10.3,')')
1004  format ( f5.1,' gb initialised')
      end

      subroutine report (description)
!
!     returns the time in the form hh:mm pm
!
      character description*(*)
      real*8    seconds
!
      call get_run_time (seconds)
      WRITE ( *,1011) seconds, trim (description)
      WRITE (98,1011) seconds, trim (description)
!
      RETURN
 1011 FORMAT (f10.3,2x,a)
      END

[/code]


Last edited by JohnCampbell on Mon Sep 29, 2008 12:41 am; edited 1 time in total
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Mon Sep 29, 2008 12:40 am    Post subject: Reply with quote

the post worked in preview, but clipped when sent. this is the rest of the code.

Code:

      subroutine get_run_time (seconds)
!
!     returns the elapsed time, accurate to .001 seconds (?)
!
      real*8 seconds
!
      CHARACTER date*8, time*10, zone*5
      INTEGER   values(8)
      real*8    start_time, x
      data start_time / -1 /
!
      call DATE_AND_TIME (date, time, zone, values)
!
      x = 60.0*60.0*values(5)     &
        +      60.0*values(6)     &
        +           values(7)     &
        +     0.001*values(8)
!   
      if (start_time < 0) start_time = x
      seconds = x - start_time
      RETURN
      END

      SUBROUTINE DATE_TIME_LABEL (LUNIT)
!
!     Displays the date and time on file unit LUNIT
!
      integer*4, intent (in)    :: lunit
!
      CHARACTER LABEL(12)*3, CBUF*22
      STDCALL   GETLOCALTIME 'GetLocalTime' (REF)
      integer*2 ia(8), YEAR,MONTH
      DATA LABEL / 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',            &
     &             'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' /
!
      call GetLocalTime (ia)
!
      year  = mod (ia(1),100)
      month = ia(2)
!
      WRITE (CBUF,1009) ia(4), LABEL(MONTH), YEAR, ia(5), ia(6), ia(7),ia(8)
 1009 FORMAT (I2,'-',A3,'-',I2.2, i3,':',i2.2,':',i2.2,'.',i3.3)
!
      WRITE (LUNIT,2001) CBUF
 2001 FORMAT (/' ** ( THIS RUN DONE AT ',A,') **')
!
      RETURN
!
      END
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Mon Sep 29, 2008 2:34 am    Post subject: Reply with quote

Paul,

I also tried various block sizes in your program with unusual results.
While 80mg blocks gives 2,768mb, the allocated memory reduces with bigger block sizes.
(> 597mg) 600mg blocks gives only 2 blocks and fails at only 1,887mb while 1,000mg blocks gives up to 2,097mb
1,200mg and above gives nothing !!

Unfortunately, I'm from old Fortran and am not familiar with pointers !

All this with FTN95_NEW_MEMORY

Code:

!     Last change:  JDC  29 Sep 2008   9:00 am
!  Program to test memory sizes
!
   real*8,    pointer :: gib(:)
!
   integer*4  i, alstat, block_size
   integer*4, parameter :: mega_byte = 1024*1024/8
   integer*8, parameter :: eight     = 8
   integer*8  size, b8
!
   write (*,*) 'megabyte ?'
   read  (*,*) i
   block_size =  i*mega_byte   ! defines 1 blocks
!
!   block_size =   80*mega_byte   ! defines 33 blocks 2,768,240,640    2,852m fail
!   block_size =  200*mega_byte   ! defines 12 blocks 2,516,582,400    2,726m fail
!   block_size =  300*mega_byte   ! defines 7 blocks  2,202,009,600    2,516m fail
!   block_size =  400*mega_byte   ! defines 5 blocks  2,097,152,000    2,516m fail
!   block_size =  500*mega_byte   ! defines 4 blocks  2,097,152,000    2,621m fail
!   block_size =  550*mega_byte   ! defines 3 blocks  1,730,150,400    2,306m fail
!   block_size =  597*mega_byte   ! defines 3 blocks  1,877,999,616    2,503m fail
!   block_size =  600*mega_byte   ! defines 2 blocks  1,258,291,200    1,887m fail
!   block_size =  800*mega_byte   ! defines 2 blocks  1,677,721,600    2,516m fail
!   block_size = 1000*mega_byte   ! defines 2 blocks  2,097,152,000    3,115m fail
!   block_size = 1100*mega_byte   ! defines 1 blocks  1,153,433,600    2,306m fail
!
!   block_size = 1200*mega_byte   ! defines no blocks
   b8         = block_size
   size       = 0
!
   do i = 1,1000
     allocate (gib(block_size),stat=alstat)
     size = size + eight*b8
     print*, i, size, alstat
     if (alstat /= 0) exit
   end do
   end
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Mon Sep 29, 2008 5:05 am    Post subject: Reply with quote

Paul,

I again modified your example to allocate multiple real*8 arrays and test the gaps between them using LOC.

Using 312,000,000 byte chunks, the allocation started at about 258 mb,
it allocated 4 blocks from 258mb to 1448 mb
it then left a 41mb gap at 1449mb and
another 261mb gap at 1787 mb
finally 3 blocks from 2048mb to 2940 mb

Do you know why it started at 258mb and what are the 2 other gaps ?
I'd expect if I used 80mb blocks, there may be other gaps.
This also shows a maximum contiguous area of 1200 mb without any influence.
Presumably when we get arrays of 1.8gb, some of these gaps are moved around.

The following is the code I used, which gave these interesting results.

Code:

!     Last change:  JDC  29 Sep 2008    1:30 pm
!  Program to test memory sizes
!   Allocate the blocks then test for contiguous memory
!
!   real*8,    pointer :: gib(:)
     real*8, allocatable, dimension(:) :: gib_1
     real*8, allocatable, dimension(:) :: gib_2
     real*8, allocatable, dimension(:) :: gib_3
     real*8, allocatable, dimension(:) :: gib_4
     real*8, allocatable, dimension(:) :: gib_5
     real*8, allocatable, dimension(:) :: gib_6
     real*8, allocatable, dimension(:) :: gib_7
     real*8, allocatable, dimension(:) :: gib_8
!
     integer*4  i, alstat, block_size
     integer*4, parameter :: mega_byte = (1000*1000)/8 ! 10^6 looks better
     integer*8  size_8
!
     write (*,*) 'megabyte ?'    ! 313 for all
     read  (*,*) i
     block_size =  i*mega_byte   ! defines 1 blocks
!
     i    = 0
     size_8 = 0
!
     allocate (gib_1(block_size),stat=alstat)
     call report (i, gib_1, size_8, block_size, alstat)
      if (alstat /= 0) goto 100
!
     allocate (gib_2(block_size),stat=alstat)
     call report (i, gib_2, size_8, block_size, alstat)
      if (alstat /= 0) goto 100
!
     allocate (gib_3(block_size),stat=alstat)
     call report (i, gib_3, size_8, block_size, alstat)
      if (alstat /= 0) goto 100
!
     allocate (gib_4(block_size),stat=alstat)
     call report (i, gib_4, size_8, block_size, alstat)
      if (alstat /= 0) goto 100
!
     allocate (gib_5(block_size),stat=alstat)
     call report (i, gib_5, size_8, block_size, alstat)
      if (alstat /= 0) goto 100
!
     allocate (gib_6(block_size),stat=alstat)
     call report (i, gib_6, size_8, block_size, alstat)
      if (alstat /= 0) goto 100
!
     allocate (gib_7(block_size),stat=alstat)
     call report (i, gib_7, size_8, block_size, alstat)
      if (alstat /= 0) goto 100
!
     allocate (gib_8(block_size),stat=alstat)
     call report (i, gib_8, size_8, block_size, alstat)
      if (alstat /= 0) goto 100
!
  100 continue
     end

!     subroutine report (n, gib, size_8, block_size, alstat)


Last edited by JohnCampbell on Mon Sep 29, 2008 5:09 am; edited 1 time in total
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Mon Sep 29, 2008 5:06 am    Post subject: Reply with quote

Again there was too much code:

Code:

     subroutine report (n, gib, size_8, block_size, alstat)
!
     integer*4 n, block_size, alstat
     real*8    gib(block_size)
     integer*8 size_8
!
     integer*8, parameter :: zero     = 0
     integer*8, parameter :: eight    = 8
     integer*8, parameter :: one_gb   = 1024*1024*1024
     integer*8  b8, m1, m2, m0, m_alloc, m_gap, two_gb, four_gb
     intrinsic  loc
     save       m0
!
     b8   = block_size
     n    = n + 1
     size_8 = size_8 + eight*b8
!     print*, n, size_8, alstat
      if (alstat /= 0) return
!
     m1 = loc (gib(1))
     m2 = loc (gib(block_size))
!
     two_gb  = one_gb + one_gb
     four_gb = two_gb + two_gb
     if (m1 < zero) m1 = m1 + four_gb
     if (m2 < zero) m2 = m2 + four_gb
!
     m2      = m2 + eight
     m_alloc = (m2-m1)
     m_gap   = 0
     if (n > 1) m_gap = m1 - m0
     m0      = m2
!
     write (*,1001) 'memory location', n, m1, m2, m_alloc, m_gap
1001 format (a,i3,2i12,i11, i10)
     end subroutine

Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Tue Sep 30, 2008 9:28 am    Post subject: Reply with quote

Paul,

I again took your program and tried to extend the "cheating" on multiple allocates for pointer arrays, to test the memory availability. I put the program in as a subroutine, so that when it exits, I thought all the allocates would be automatically deallocated (fortran standard ?). This does not appear to work.
However with a block size of 20mb, it shows in more detail what areas of memory are not available. The program also appears to confirm that the /3gb switch is providing the 3gb of accessible memory.
I'm assuming the contiguous areas can be addressed as merged blocks. I will take the previous real*8 array program in an earlier post and confirm if this works.

It remains to be able to shift the "unavailable parts" to a better area to maximise the size of contiguous available memory. Isn't this what Slink does ?

Code:

!     Last change:  JDC  30 Sep 2008    9:53 am
!
   call test_contiguous (20)
   call test_contiguous (40)   ! this call failed
   call test_contiguous (80)
   call test_contiguous (120)
   call test_contiguous (200)
   call test_contiguous (400)
   call test_contiguous (600)
   call test_contiguous (800)
   end

   subroutine test_contiguous (block_mb)
!
!  subroutine to test memory sizes and contiguous allocation
!
   integer*4  block_mb
!
   real*8,    pointer :: gib(:)
!
   integer*4  i, alstat, block_size
   integer*4, parameter :: mega_byte = 1024*1024/8
   integer*8, parameter :: zero      = 0
   integer*8, parameter :: four      = 4
   integer*8, parameter :: eight     = 8
   integer*8, parameter :: one_gb    = 1024*1024*1024
   integer*8, parameter :: four_gb   = one_gb*four
   integer*8  size, b8, js,je
   real*8     mgs, mge, mgg, mgl
!
   write (*,*) 'Testing block size ',block_mb,'mb'
   block_size = block_mb*mega_byte    ! defines 1 block in real*8
!
   b8   = block_size*eight
   size = 0
   mgl  = 0    ! last end
!
   do i = 1,1000
     allocate (gib(block_size),stat=alstat)
! cumulative size (bytes)
     size = size + b8                                                   
! start and end address (bytes)
     js = loc(gib(1))           ; if (js < zero) js = js + four_gb     
     je = loc(gib(block_size))  ; if (je < zero) je = je + four_gb     
! start and end address (mb)
     mgs = dble(js) / 1024./1024.                                     
     mge = dble(je) / 1024./1024.                                     
! gap size (mb)
     mgg = mgs - mgl
     mgl = mge
     write (*,2001) i, size, alstat, js,je, mgs, mgl, mgg
2001 format (i5, i12, i5, 2i12, 3f10.2)
     if (alstat /= 0) exit
   end do
! hopefully release allocated memory
   end subroutine test_contiguous
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Wed Oct 01, 2008 3:35 am    Post subject: Reply with quote

Paul,

I took the memory test subroutine and placed it in the large program I am wanting to use for extended memory.
I ran it at the start for a number of different working array sizes, with and without /3gb switch in slink.

1) without the 3gb in slink, only 2gb of memory is accessible.

2) with 300mb working array, i get a memory usage of :
first 371 mg is taken by program ( 300mb + 71mb)
at 1429mb, there is a 24.6mb gap
at 1486mb, a 3.5mb gap
at 1874mb, a 46.1mb gap
at 1984mb, a 63.9mb gap

3) with 1000mb working, a similar set of gaps

4) with 1600mb working array, i get a memory usage of :
first 1664 mg is taken by program ( 1600mb + 64mb)
gaps at 1429mb and 1486mb have been overwritten, ie omitted
at 1889mb, 46.1mb gap has been reduced to 30.8mb
at 1984mb, a 63.9mb gap

5) with 1750mb, similar (.map version)

ie, the gaps have been removed and do not appear to have been shifted

I did not run the program past the memory test.
There appears to be 3 parts of memory reserved for a small program, but only 2 for a larger program.
If the program encroaches on the 2 beyond 1889mb, then it becomes an illegal .exe
What are these 3 parts of memory being used for ?
Can they be relocated, perhaps to 2900mb or possibly to 64mb, and place the .bss section after them ?

I am attaching to an email the memory availability dump I generated from the memory scanning subroutine for these 5 tests and the last .map file for the program.

I did not run the program.
I have not yet tested the earlier real*8 array test to see if the memory allocated is useable.

Does this make any sense ?

Regards

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8320
Location: Salford, UK

PostPosted: Mon Oct 06, 2008 11:55 am    Post subject: Reply with quote

Ian

I have not managed to find your sample code.
Can you send it again please to my hotmail account.

Paul
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Mon Oct 06, 2008 10:10 pm    Post subject: Reply with quote

Paul,

It appears that the attachments may have been deleted, as they contained .exe files. I will send it again, without the .exe.
I have included all the recent test programs.
Please let me know if the attachments are not there this time. Otherwise I will have to use my home email account !

John
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2629
Location: Sydney

PostPosted: Wed Oct 08, 2008 5:08 am    Post subject: Reply with quote

Paul,

I have done a review of the large program I am wanting to run in 3gb of memory. The following is an approximate breakdown of the memory usage in the .map file:-

0.64mb .text - which is my code
0.12mb .data - which is salflibc/kernel32
0.69mb .salfdbg - presumably due to link map and /debug compilation
1.93mb .bss - my common excluding the big array

The total memory usage is 3.44 mb, excluding the big array

In summary, the memory usage, excluding the big array would be 0.1% of memory.

To use anything significantly above 2gb, the big array must be 99.9% of this. Either I must be able to have a single array bigger than 2gb or I have a major rewrite to use 2 big arrays or "chunks" in my algorithm.

The example problem I have been targeting to use for this /3gb approach requires an array of about 2.4gb in size. Will this be a possibility ?

Are any other forum users interested in this /3gb facility ?

Paul, thanks again for your assistance with this.

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8320
Location: Salford, UK

PostPosted: Wed Oct 08, 2008 8:17 am    Post subject: Reply with quote

John

My understanding is that you cannot have a single array of more than 2GB.
Apart from rewriting your code, the only possible way forward would be to try running your program under WOW on a 64 bit machine and operating system. I don't know if anyone has tried this but you may be able to get 4GB this way. Alternatively you would have to switch to a 64 bit compiler, machine and operating system.

Paul
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2959
Location: South Pole, Antarctica

PostPosted: Sat Oct 11, 2008 5:52 pm    Post subject: Re: Reply with quote

PaulLaidler wrote:

try running your program under WOW

World of Warcraft? Very Happy
For me 32bit is dead 15 years ago when I painfully hit its 1.6GB limit. Great that 32bit is finally dead starting with this fall shopping season. No single laptop in Best Buy or Frys right now is selling with 32bit XP (only one is the pocket EEE laptop), all are with 64bit Vista running 3-4 GB RAM.
For $99 total you can upgrade your desktop PC motherboard and 64bit processor, for $49 you'll get 4GB RAM (this month prices in Frys). You can get 64bit OEM Vista for cheap or use 64bit XP. The only what lagging are 64bit compilers. What is general obstacle to rewrite compiler for 64bit OS?

JohnCampbell wrote:

Are any other forum users interested in this /3gb facility ?

waste of time, I am sure you push a wrong button. With 64bit compiler you will get not factor 1.5-2 but many orders of magnitude more (well, of course Microsoft will restrict you just to not to forget who is the boss). That will totally change the way of thinking about your future algorithms
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group