Я изо всех сил пытался найти какую-либо конкретную информацию при проектировании производного типа. Я думаю, что лучший способ обсудить это - это несколько вариантов. Я составил несколько разделов кода с различными приложениями производного типа. Я бы предпочел использовать динамические массивы для nparts
, index
и refs
. Я пропустил разделы кода, который фактически использует структуру (нет, потому что я ее создал), но примеры показаны, и в обычной программе я намерен использовать все значения в структуре хотя бы один раз.Проектирование производного типа с элементами массива
Вариант A: Использование статических массивов в производном типе. Недостатком является то, что мне придется угадать размер массива во время компиляции.
! Known before compile time.
nboxes = 5000
max_parts = 2000
packs = 10
Type Boxes
Sequence
Integer :: location, date
Integer, Dimension(0:packs) :: nparts
Integer, Dimension(max_parts,packs) :: index
Real(Kind=8), Dimension(packs,packs) :: refs
End Type Boxes
type(boxes), dimension(:), allocatable :: assembly
allocate(assembly(nboxes))
! Perform some operations on assembly...
do i = 1,nboxes
do j = 1,packs
do k = j,packs
example = assembly(i)%nparts(k) - assembly(i)%nparts(j)
.
.
do m = 1,max_parts
example = assembly(i)%index(m,j) + assembly(i)%refs(k,j) * assembly(i)%nparts(j)
.
.
end do
end do
end do
end do
Вариант B: Использовать динамические массивы в производном типе.
! Defined during execution. Much better.
nboxes = 5000
max_parts = 2000
packs = 10
Type Boxes
Sequence
Integer :: location, date
Integer, Dimension(:), Allocatable :: nparts
Integer, Dimension(:,:), Allocatable :: index
Real(Kind=8), Dimension(:,:), Allocatable :: refs
End Type Boxes
type(boxes), dimension(:), allocatable :: assembly
allocate(assembly(nboxes))
do i = 1,nboxes
allocate(assembly(i)%nparts(0:packs))
allocate(assembly(i)%index(max_parts,packs))
allocate(assembly(i)%refs(packs,packs))
end do
! Perform some operations on assembly...
do i = 1,nboxes
do j = 1,packs
do k = j,packs
example = assembly(i)%nparts(k) - assembly(i)%nparts(j)
.
.
do m = 1,max_parts
example = assembly(i)%index(m,j) + assembly(i)%refs(k,j) * assembly(i)%nparts(j)
.
.
end do
end do
end do
end do
Вариант C: минимизировать количество динамических массивов, используемых в производном типе и силы, чтобы стать assembly
массив. Обратите внимание, что в этой версии у нас есть куча неиспользуемой памяти. Например, nparts
и index
требуется память packs
- с assembly(packs,packs,nboxes)
.
! Defined during execution. Much better.
nboxes = 5000
max_parts = 2000
packs = 10
Type Boxes
Sequence
Integer :: location, date, nparts, index
Real(Kind=8) :: refs
Integer, Dimension(:), Allocatable :: index
End Type Boxes
type(boxes), dimension(:,:,:), allocatable :: assembly
allocate(assembly(packs,packs,nboxes))
do i = 1,nboxes
do j = 1,packs
do k = 1,packs
allocate(assembly(k,j,i)%index(max_parts))
end do
end do
end do
! Perform some operations on assembly...
do i = 1,nboxes
do j = 1,packs
do k = j,packs
example = assembly(k,j,i)%nparts - assembly(k,j,i)%nparts
.
do m = 1,max_parts
example = assembly(k,j,i)%index(m) + assembly(k,j,i)%refs * assembly(k,j,i)%nparts
.
.
end do
end do
end do
end do
Вариант D: Еще одна перестановка Вариант C.
Вопросы:
- Какой вариант правильный/ожидается, метод проектирования производного типа, например,
do
петли показали? Какая версия наиболее оптимизирована, учитывая, что мне нужны возможности динамического массива? - Возможно, связано с выше. Как выделена и доступна память? Возможно ли использование
SEQUENCE
? Я думаю, что выделенные массивы не появятся в последовательности в любом случае. Разве этот пункт не был бы лучшим вариантом, поскольку каждый раздел изassembly
меньше? - Должен ли я разделить этот производный тип на несколько производных типов или вообще избавиться от него и просто придерживаться переменных? Я буду использовать этот производный тип в нескольких процедурах и поместил бы его в модуль.
Поддерживает ли ваш компилятор параметризованные производные типы? – francescalus
Это правда, хотя я не знаком с концепцией и приложением. Так что мой разум еще не поддерживает его. :) – Higgy
'kind = 8' действительно уродливый, избегайте волшебных констант! Это не означает 8 байтов! По крайней мере, не во всех компиляторах. –