2013-02-13 2 views
3

В моем коде Fortran я хочу использовать неровные массивы с несколькими уровнями распределения. Пример кода, который я имею в виду, этоЕсть ли проблемы с использованием зубчатых массивов в Fortran с несколькими уровнями распределения?

module nonsquare_matrix_mod 
implicit none 

    type :: nonsquare_matrix 
     integer :: d 
     real*8, dimension(:), allocatable :: vector 
    end type nonsquare_matrix 

    type(nonsquare_matrix),dimension(:),allocatable :: mymatrix 

end module nonsquare_matrix_mod 

program nonsquare_matrix_test 
    use nonsquare_matrix_mod 
    implicit none 

integer, parameter :: max_size=50 
integer :: i 

allocate(mymatrix(max_size)) 
do i=1,max_size 
    allocate(mymatrix(i) % vector(i)) 
end do 

print *, "allocated" 


end program 

Я хочу реализовать эту стратегию программирования, чтобы сохранить память. Я знаю, что память, сохраненная в этом примере, не слишком велика, но для моего фактического проекта я работаю с гораздо большими структурами данных. Мне было интересно, есть ли какие-либо опасности в этой практике программирования, такие как данные, которые не хранятся постоянно или более подвержены утечкам памяти. Или это полезный способ экономии памяти без многих недостатков? Благодарю.

+1

выглядит хорошо для меня, и я использовал этот подход в прошлом , Сколько сохраненной памяти будет зависеть от изменения длины массива между массивами. Лучше всего сначала написать код, наиболее интуитивный для вас. Я бы не стал беспокоиться о утечке памяти, пока вы держитесь подальше от указателей. – milancurcic

ответ

4

Поскольку вы используете только распределяемые массивы, у вас не будет утечки памяти, поскольку это может иметь место при использовании указателей. Является ли ядровый массив разумным решением для вашей проблемы, во многом зависит от структуры ваших данных. Следует отметить несколько замечаний:

  • Ваш массив не будет наклонным. Это имеет несколько последствий, например, хуже поведение кэширования, когда вы получаете доступ к последующим строкам.

  • Вы должны выделить каждую строку через allocate отдельно. Если это происходит очень часто (например, внутри цикла), это может быть проблемой, так как распределение является довольно «медленной» операцией.

  • Если строки в вашем массиве действительно очень разные по размеру (и у вас не слишком много строк), вы можете сэкономить значительное количество памяти.

Если длина линий устанавливаются в момент их создания и не изменилась после (и у вас есть хорошая догадка максимально сколько элементов вы будете иметь во всем массиве), можно выделить большой буфер массив, где вы положили в строках, и массив индекса, который содержит позицию первого элемента этой строки в массиве буфера:

program nonsquare_matrix_test 
    implicit none 

    integer, parameter :: dp = kind(1.0d0) 
    integer, parameter :: maxlines = 50 
    integer, parameter :: maxelements = 5000 
    real(dp), allocatable :: buffer(:) 
    integer, allocatable :: rowindex(:) 
    integer :: ii 

    allocate(buffer(maxelements)) 
    allocate(rowindex(maxlines + 1)) 
    rowindex(1) = 1 
    do ii = 1, maxlines 
    rowindex(ii + 1) = rowindex(ii) + ii 
    end do 
    ! ... 
    ! Omitting the part which fills up the array 
    ! ... 
    ! Accessing a given line (e.g. line 5) 
    print *, "Content of line 5:" 
    print *, buffer(rowindex(5):rowindex(6)-1) 

end program nonsquare_matrix_test 

 Смежные вопросы

  • Нет связанных вопросов^_^