Параллельные вычисления в ИММ УрО РАН
 
 

Назад

 

В начало

Далее

Обработка больших массивов

 Речь пойдет о

 средствах динамической памяти,

 указателях,

 операциях и средствах типовой обработки массивов,

 средствах образования и обработки вырезок (сечений).

 о паспорте (образе) массива, содержащим сведения о размерности и размерах по каждому измерению.

Динамический массив

Динамический массив реализуется через механизм "кучи", из которой память для массивов выделяется по мере поступления запросов.

В ниже приведенном примере с помощью атрибута ALLOCATABLE объявляются динамическими массивы matrix и vector, для которых потом с помощью оператора ALLOCATE запрашивается требуемое пространство памяти. Функция ALLOCATED определяет, была ли выделена память. Оператор DEALLOCATE возвращает ранее выделенную память в "кучу"

PROGRAM ALLOCM

INTEGER, ALLOCATABLE :: matrix( : , : )

REAL , ALLOCATABLE :: vector( : )

N = 2

ALLOCATE (matrix(3,5),vector(-2:N+2))

DO I = 1, 3

DO J=1,5

matrix(i,j) = i*j

END DO

END DO

K = N+2

DO I = 1, K

vector(I) = I

END DO

IF ( ALLOCATED(matrix) ) write(*, '(a12)') 'alloc matrix'

IF ( ALLOCATED(vector) ) write(*, '(a12)') 'alloc vector'

DEALLOCATE (matrix,vector)

IF (.not. ALLOCATED(matrix)) write(*, '(a15)') 'no alloc matrix'

IF (.not. ALLOCATED(vector)) write(*, '(a15)') 'no alloc vector'

END

Пример показывает также использование оператора цикла DO в паре с оператором END DO, что позволяет обойтись без меток для операторов, заканчивающих тело цикла.

Паспорт (образ) массива

Паспорт (образ) массива содержит информацию о размерности массива и протяженности (размеру) по каждому измерению. Таким образом, паспорт - это вспомогательный массив размера, равного числу измерений в основном массиве.

INTEGER VEC(2)

REAL array(3:10,-1:3)

VEC=SHAPE(array)

WRITE (*,*) VEC

END

Функция SHAPE извлекает из массива array размеры по каждому измерению, то есть число элементов в каждом измерении. Паспорт записывается в массив VEC (это числа 8 и 5).

Оператор WRITE (*,*) VEC напечатает числа 8 5

 В следующем ниже примере программа опредеяет, совместимы ли массив MASK типа LOGICAL и массив A типа REAL, то есть одинаковы ли их образы. Оба массива трехмерные.

С помощью функции SHAPE создаются трехэлементные одномерные массивы B и C, содержащие образы массивов A и MASK соответственно. Массивы B и C поэлементно сравниваются и в качестве результата вычисляется переменная conform, значение которой равно .TRUE. или .FALSE.

LOGICAL, ALLOCATABLE :: MASK(:,:,:)

REAL, ALLOCATABLE :: A(:,:,:)

INTEGER B(3), C(3)

LOGICAL conform

ALLOCATE (A(5,4,3))

ALLOCATE (MASK(5,4,3)

IF (ALLOCATED (A). AND. ALLOCATED(MASK)) THEN

B = SHAPE(A); C = SHAPE(MASK)

IF ((B(1) .EQ. C(1)) .AND. (B(2) . EQ. C(2)) .AND. .(B(3) . EQ. C(3)) THEN

IF ((B(1) .EQ. C(1)) .AND. (B(2) . EQ. C(2)) .AND. .(B(3) . EQ. C(3)) THEN

conform = .TRUE.

ELSE

conform = .FALSE.

END IF

WRITE (*,*) conform

END 

 

Указатели и адресаты

В целях расширения аппарата для работы с массивами как и в ряде развитых языков в Фортран 90 внесены средства доступа к данным по указателям. Но в связи с особенностями реализации языка и для целей защиты от ошибок вводится для указателей область доступа - перечисляются те переменные, на которые могут быть установлены указатели. Эти переменные называются адресатами. При описании указателей нужно сообщать свойства предполагаемых адресатов. Для указателей тоже описываются их свойства. Такой подход позволяет компилятору на стадии трансляции обнаружить несоответствия свойств указателя и адресата, что обеспечит правильное построение ссылок на стадии выполнения программы.

Наиболее эффективен аппарат указателей для массивов.

 Примеры описания указателей и их возможных адресатов:

REAL, POINTER :: pt1

REAL, TARGET :: a, b, c, d, e

INTEGER, TARGET :: a(3), b(6), c(9)

INTEGER, DIMENSION(:),POINTER::pt2

 На стадии выполнения указатель и адресат связываются оператором присваивания (=>):

pointer => target,

после чего указатель pointer начинает указывать на переменную target.

Пример

INTEGER, POINTER :: pt

INTEGER, TARGET :: x=34, y=0

 ...

pt => x ! pt указывает на x

y = pt ! y эквивалентно x

pt => y ! pt указывает y

pt = 17 ! y эквивалентно 17

Операции над массивами

Весьма мощным инструментом для работы с массивами является набор операций над массивами:

 конструктор массива

 операции с вырезками

 выборка по условию,

 суммирование, умножение элементов, удовлетворяющих условию

 большой набор встроенных функций

Ниже приведен небольшой пример конструктора массива. Массив t типа INTEGER создается путем задания значений его 5 элементов. Значения задаются так же как в операторе DATA. Массив v генерируется путем рассылки с чередованием пар двух значений 1 и 0. В массив A с помощью неявного цикла засылается значение 0. А массив B вычисляется путем прибавления к значениям элементов массива A одного и того же значения 1.3.

INTEGER :: t(5) = (/1, 2, 1, 1, 3/)

INTEGER :: v(1000000) = (/ (1,0, j=1,500000)/)

real ::A(1000,1000)= ( /((A(i,j)=0,i=1,1000),j=1,1000)/)

real::B(1000,1000)= (/((A(j,k)+1.3,j=1,1000),k=1,1000)/)

 В следующем примере массив конструируется с помощью функции конструирования SPREAD.

 REAL, DIMENSION(3) :: a=(/2,3,4/)

REAL, DIMENSION(3,3) :: b, c

b =SPREAD(a, DIM=1, NCOPIES=3)

c=SPREAD(a, DIM=2, NCOPIES=3)

 Массивы b и c конструируются из значений массива a.

Массивы b строится путем 3-кратного копирования (NCOPIES=3) массива a по 1-му измерению (DIM=1). Будут получены 3 строки, содержащие значения 2,3,4.

2

3

4

2

3

4

2

3

4

 Массивы c строится путем 3-кратного копирования (NCOPIES=3) массива a по 2-му измерению (DIM=2). Будут получены 3 столбца, содержащие значения 2,3,4.

2

2

2

3

3

3

4

4

4

Большое число поэлементных операциях применимы к совмесимым массивам.

PROGRAM multM

REAL :: ve1, ve2(1:3)

REAL :: ve3, ve4(1:3)

DO I = 1, 3

ve1 (I) = I

ve2 (I) = I+1

END DO

ve3=ve1+ve2

write (*,'(3f4.1)') ve3(1),ve3(2),ve3(3)

ve4=ve1-ve2

write (*,'(3f4.1)') ve4(1),ve4(2),ve4(3)

ve4=ve1*ve2

write (*,'(3f6.1)') ve4(1),ve4(2),ve4(3)

 

Пример показывает возможность поэлементных операций над массивами ve1 и ve2 для получения массивов ve3, ve4, ve5.

Поэлементные операции над вырезками

Вырезка из массива берется по разному: строка, столбец, часть строк или столбцов подряд или выборка строк (столбцов) с шагом, прямоугольная вырезка.

Вырезка имеет свой образ, определяемый размерностью и размерами (например, строка или столбец матрицы - одномерные массивы).

Примеры вырезок (сечений, секций) массивов

REAL, DIMENSION(8) :: a

INTEGER, DIMENSION(5,4) :: b

INTEGER, DIMENSION(5,6) :: Q

INTEGER :: i=3

...

a(3:5) ! элементы 3, 4, 5

a(1:5:2) ! элементы 1, 3, 5

b(1:2,2:i) ! элементы (1,2) (2,2) (1,3) и (2,3)

(i,1:4:2) ! элементы 1 и 3 из 3-й строки

b(2:4,1) ! элементы 2, 3, 4 из 1-й колонки

Q(1,1:6)=(/13,11,25,2,1,9/)! 1-я строка, элементы с 1-го по 6

Q(2,1:6)=(/9,3,31,14,52,27/) ! 2-я строка

Q(3,1:6)=(/16,45,54,36,15,20/) ! 3-я строка

Q(4,1:6)=(/7,20,18,19,8,19/) ! 4-я строка

Q(5,1:6)=(/37,56,54,66,77,90/) ! 5-я строка

Q((/1,2,3,4,5/),2)=(/11,3,45,20,56/) ! 2-й столбец

Q((/1,2/),(/5,6/))=((/ 1,9/),(/ 52,27/)) ! в 1-й, 2-й строках, 5,6 элементы

Примеры операций с вырезками:

REAL, DIMENSION(10) :: alpha, beta

REAL :: gamma(20)

...

alpha(1:5) = 2.0 ! первые 5 элементов равны 2.0

alpha(6:) = 0.0 ! элементы с 6 по 10 равны 0.0

...

beta(1:10:2) = alpha(1:5)/6 ! вырезки массива

alpha(2:10) = alpha(1:9

gamma(11:20) = beta

В массиве beta элементы с номерами 1,3,5,7,9 (то есть с 1-го по 10-й с шагом 2) вычисляются путем деления элементов массива alpha на 6. Из alpha берутся элементы с 1-го по 5-й.

Затем в массиве alpha элементы с 1-го по 9-й перемещаются на 1 позицию вправо, таким образом создаются элементы с 2-го по 10-й.

В массиве gamma элементы с 11-го по 20-й берутся из массива beta (элементы с 1-го по 10-й).

Заметим, что левая и правая части операторов присваивания содержат совместимые массивы. Операция деления в выражении alpha(1:5)/6 проводится над пятью элементами, но с одним и тем же делителем.

Операторы для условной обработки массивов

 

INTEGER :: A, B, C (20,30)

...

WHERE( A<0 ) A = 0

WHERE( A**2>10 ) A = 999

WHERE( A/=0 ) A = 1/A

WHERE (C .gt. 0) A = B/C

 Во всех приведенных операторах приводятся условия, проверяемые для каждого из элементов массива. При истинности условия для конкретного элемента массива для этого элемента выполняются действия, задаваемые в операторе WHERE. В операторе ) A = B/C в операции используются соответствующие элементы массивов.

Встроенные функции и процедуры для работы с массивами

Имеется большой набор встроенных функций и процедур для работы с массивами. Их можно разделить на 7 тематических групп:

  1. Умножение векторов и матриц
  2. Упрощение
  3. Исследование
  4. Конструирование
  5. Реорганизация
  6. Манипуляции
  7. Локализация (указание )

 Например, функция COUNT подсчитывает в массиве число элементов, удовлетворяющих условию. Фунция MAXVAL определяет максимальное значение элемента из тех, которые удовлетворяют условию. Функция SUM возвращает сумму элементов, удовлетворяющих условию. И т.д.

Параллелизм данных

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

Назад

 

В начало

Далее