Fortran: RAM needed for simple arrays and objects that store the same amount of data

Trying to store some data using dynamic memory allocation in two different ways, I notice a huge difference in operational requirements, which I cannot explain. Some insight would be appreciated.

In the following examples, the goal is to create a database that stores the identifiers of the edges associated with a node in a polygon mesh. However, the nature of the problem does not matter.

Case 1, using "simple" arrays:

program memorytest implicit none integer, dimension(:, :), allocatable :: node_edges integer :: i allocate(node_edges(10, 10000000)) ! 10000000 nodes with 10 edges each node_edges(:, :) = 0 read *, i ! pause deallocate(node_edges) end program memorytest 

Required RAM: ~ 395 500 K

Case 2 using node type:

 program memorytest implicit none type node integer, dimension(:), allocatable :: edges end type type(node), dimension(:), allocatable :: nodes integer :: i allocate(nodes(10000000)) ! 10000000 nodes do i = 1, 10000000 allocate(nodes(i)%edges(10)) ! with 10 edges each end do do i = 1, 10000000 nodes(i)%edges(:) = 0 end do read *, i ! pause do i = 1, 10000000 deallocate(nodes(i)%edges) end do deallocate(nodes) end program memorytest 

Required RAM: ~ 1060 500 K

For comparison, I tried using equivalent approaches in C ++.

Case 1, using "simple" arrays:

 #include "stdafx.h" #include <iostream> int main() { int** node_edges; int i, j; node_edges = new int*[10000000]; // 10000000 nodes for(i = 0; i < 10000000; i++) node_edges[i] = new int[10]; // with 10 edges each for(i = 0; i < 10000000; i++) for(j = 0; j < 10; j++) node_edges[i][j] = 0; std::cin >> i; // pause for(i = 0; i < 10000000; i++) delete [] node_edges[i]; delete [] node_edges; return 0; } 

Required RAM: ~ 510 000 K

Case 2 using the node class:

 #include "stdafx.h" #include <iostream> class node { public: int* edges; }; int main() { node* nodes; int i, j; nodes = new node[10000000]; // 10000000 nodes for(i = 0; i < 10000000; i++) nodes[i].edges = new int[10]; // with 10 edges each for(i = 0; i < 10000000; i++) for(j = 0; j < 10; j++) nodes[i].edges[j] = 0; std::cin >> i; // pause for(i = 0; i < 10000000; i++) delete [] nodes[i].edges; delete [] nodes; return 0; } 

Required RAM: ~ 510 000 K

Development environment used: Intel Visual Fortran Studio XE 2013 and MS Visual C ++ 2010, respectively, producing 32-bit executables in "Release" mode by default.

As already noted, C ++ uses exactly the same amount of RAM for both approaches. In Fortran, I would justify some minor differences, but I cannot explain. For me, this looks like something with either Fortran itself or with the Intel fortran compiler flag, which I don't know about.

Any ideas why this is happening and / or any suggestions to avoid this excessive RAM requirement in Fortran's object-oriented approach?

Thanks in advance.

+7
arrays oop fortran ram
source share
1 answer

It should be borne in mind that the distribution of a two-dimensional array and one-dimensional arrays is different. For example:

  allocate(node_edges(10, 100)) 

Allocates one block of memory, which can contain 1000 elements.

  allocate(nodes(100)) ! 10000000 nodes do i = 1, 100 allocate(nodes(i)%edges(10)) ! with 10 edges each end do 

Allocates one block, which can contain 100 elements and each of which has 10 subitems. The same number of elements, the same memory usage?

Not. In the second case, you have allocated 100 new arrays. Everyone has overhead. In Fortran, this can be quite high since it needs to track the size of the array — you might want to tackle the array section later. This is especially noticeable when the size of the distribution is small. In this case, it is equal to 10, and with additional information about the array plus the addition can double the allocated size - which it has in your case.

+9
source share

All Articles