Программирование с использованием технологии OpenMP
Программирование на Фортране
Меню сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Форма входа

Поиск

Друзья сайта

Приветствую Вас, Гость · RSS 04.08.2025, 05:41

Программы на Фортране с использованием технологии OpenMP

Умножение матриц

Ниже приведена тестовая программа умножения матриц. В этой программе есть блок обычного умножения и параллельного умножения с использованием технологии OpenMP.

program my_transpose
include "omp_lib.h"
double precision start_time, end_time, tick
real(8), allocatable, target :: A(:,:)
real(8), allocatable, target :: C(:,:)
integer N,i,j,k
write(*,*) "N="
read(*,*) N
allocate(A(N,N))
write(*,*) "Создание матрицы"
start_time = omp_get_wtime()
do i=1,N
do j=1,N
A(i,j)=sin(i*1.0)*cos(j*1.0)
end do
end do
end_time = omp_get_wtime()
tick = omp_get_wtick()
print *, "Время генерации матрицы", end_time-start_time
print *, "Точность таймера ", tick
write(*,*)
allocate(C(N,N))
write(*,*) "Последовательное умножение"
write(*,*)
start_time = omp_get_wtime()
do i=1,n
do j=1,n
c(i,j)=0
do k=1,n
c(i,j)=c(i,j)+a(k,i)*a(k,j)
end do
end do
end do
end_time = omp_get_wtime()
tick = omp_get_wtick()
print *, "Время на последовательного умножения ", end_time-start_time
print *, "Точность таймера ", tick
write(*,*)
write(*,*) "Параллельное умножение"
write(*,*)
start_time = omp_get_wtime()
!$omp parallel do shared(a, c) private(i, j, k)
do i=1,n
do j=1,n
c(i,j)=0
do k=1,n
c(i,j)=c(i,j)+a(k,i)*a(k,j)
end do
end do
end do
write(*,*)
end_time = omp_get_wtime()
tick = omp_get_wtick()
print *, "Время параллельного умножения", end_time-start_time
print *, "Точность таймера ", tick
deallocate(A)
deallocate(C)
end

Тестирование программы проходило на ПК с материнской платой MSI H67MA-E45, процессор Intel Core I5 (3.3 Ггц), ОЗУ 4 Гб, ОС Xubuntu 11.10 c pae ядром, компилятор g++ 4.6.

Результаты тестирования представлены в таблице 1 и на рис. 1.

Таблица 1.


Время, с
Размерность матрицы
200
500
1000
1500
2000
2500
3000
3500
4000
1 ядро, Fortran
0.0530.62
5.1
17.1
41.22
78.63
135.8
215.28
322.06
4 ядра, Fortran0.022
0.31
2.6
8.57
20.33
39.39
68.83
108.57
162.19




Рисунок 1

Решение СЛАУ методом простой итерации

Ниже приведена тестовая программа решения СЛАУ, система уравнений формировалась, удовлетворяющая условию сходимости, с диагональным преобладанием. В этой программе есть подпрограммы обычного и параллельного (с использованием технологии OpenMP) решения СЛАУ методом простой итерации.

program my_transpose
include "omp_lib.h"
double precision start_time, end_time, tick
real(8), allocatable, target :: A_(:,:)
real(8), allocatable, target :: X_(:)
real(8), allocatable, target :: B_(:)
integer N_,i,j,k
write(*,*) "N="
read(*,*) N_
allocate(A_(N_,N_))
allocate(B_(N_))
allocate(X_(N_))
print *, "В системе",omp_get_num_procs()," процессоров"
do i=1,N_
do j=1,N_
if (i == j) then
A_(i,j)=1
else
A_(i,j)=0.1/(i+j-2)
end if
end do
end do
do i=1,N_
B_(i)=sin(i*1.0)
end do
write(*,*)
write(*,*) "Последовательное решение СЛАУ методом Якоби"
start_time = omp_get_wtime()
call jacobi_posl(A_,B_, X_, N_, 1e-6,kol)
end_time = omp_get_wtime()
print *, "Время на счёта ", end_time-start_time
print *, "Количество итераций ", kol
write(*,*) "Параллельное решение СЛАУ методом Якоби"
start_time = omp_get_wtime()
call jacobi_pll(A_,B_, X_, N_, 1e-6,kol)
end_time = omp_get_wtime()
print *, "Время на счёта ", end_time-start_time
print *, "Количество итераций ", kol
write(*,*)
deallocate(A_)
deallocate(X_)
deallocate(B_)
contains

subroutine jacobi_posl(a, b, x, N, ep,kvo)
integer, intent (in):: N
real, intent (in):: ep
real(8), intent (in):: a(N,N), b(N)
real(8), intent (inout):: x(N)
integer, intent (inout):: kvo
integer i,j
real(8), allocatable, target :: alf(:,:)
real(8), allocatable, target :: bet(:)
real(8), allocatable, target :: x0(:)
real(8) maxx
allocate(alf(N,N))
allocate(bet(N))
allocate(x0(N))
do i=1,N
bet(i)=b(i)/a(i,i)
do j=1,N
if (i==j) then
alf(i,j)=0
else
alf(i,j)=-a(i,j)/a(i,i)
end if
end do
end do
x=bet
kvo=0
maxx=5*ep;
do while (maxx>=ep)
x0=x
x=MATMUL(alf,x0)+bet
maxx=MAXVAL(abs(x0-x))
kvo=kvo+1
end do
deallocate(alf)
deallocate(bet)
deallocate(x0)
end subroutine jacobi_posl
subroutine jacobi_pll(a, b, x, N, ep,kvo)
integer, intent (in):: N
real, intent (in):: ep
real(8), intent (in):: a(N,N), b(N)
real(8), intent (inout):: x(N)
integer, intent (inout):: kvo
integer i,j
real(8), allocatable, target :: alf(:,:)
real(8), allocatable, target :: bet(:)
real(8), allocatable, target :: x0(:)
real(8) maxx
allocate(alf(N,N))
allocate(bet(N))
allocate(x0(N))
!$omp parallel do shared(a, b)
do i=1,N
bet(i)=b(i)/a(i,i)
do j=1,N
if (i==j) then
alf(i,j)=0
else
alf(i,j)=-a(i,j)/a(i,i)
end if
end do
end do
x=bet
kvo=0
maxx=5*ep;
do while (maxx>=ep)
x0=x
x=MATMUL(alf,x0)
x=x+bet
maxx=MAXVAL(abs(x0-x))
kvo=kvo+1
end do
deallocate(alf)
deallocate(bet)
deallocate(x0)
end subroutine jacobi_pll
end

Тестирование программы проходило на ПК с материнской платой MSI H67MA-E45, процессор Intel Core I5 (3.3 Ггц), ОЗУ 4 Гб, ОС Xubuntu 11.10 c pae ядром, компилятор g++ 4.6.

Результаты тестирования представлены в таблице 2 и на рис. 2.

Таблица 2.

Время, с
 Размерность матрицы
50010002000
5000
7000
8000
9000
10000
11000
1 ядро, Fortran
0.00490.0220.103
0.76
1.5
3.29
2.7
4.01
4.7
4 ядра, Fortran
0.00230.0110.049
0.32
0.79
1.92
2.13
3.2
4.01



Рисунок 2
Copyright MyCorp © 2025
Бесплатный хостинг uCoz