Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Распараллеливание программ. Учебник
.pdf
151
> {A, B} = {[1,2,3], {x,y}}.
{[1,2,3],{x,y}}
> A.
[1,2,3]
> B.
{x,y}
> [a,X,b,Y] = [a,{hello, fred},b,1].
[a,{hello,fred},b,1]
> X.
{hello,fred}
> Y.
> {_,L,_} = {fred,{likes, [wine, women, song]},
{drinks, [whisky, beer]}}.
{fred,{likes,[wine,women,song]},{drinks,[whisky,beer]}}
> L.
{likes,[wine,women,song]}
-module(lists1).
-export([reverse/1]).
reverse(L) ->
reverse(L, []).
reverse([H|T], L) ->
reverse(T, [H|L]);
reverse([], L) ->
L .
spawn/3
send receive
функцией spawn(Mod,
Function, Ops)Function
Mod Ops
send
Pid ! Message
PidMessage
receive
Message1 [ when Guard1 ] ->
...;

152
Message2 [ when Guard2 ] ->
...;
...
[after Timeout ->
... ]
end
Message#Guard#Timeout
Значение
таймаута
Целое
положительное
число
innity таймаут никогда не произойдет
0 таймаут произойдет немедленно, но сначала попытаемся принять
Описание
таймаут произойдет через указанное количество миллисекунд
первое сообщение, которое уже в почтовом ящике.
-module(echo).
-export([start/0, loop/0]).
start() ->
spawn( echo , loop , [] ).
loop() ->
receive
{ From , Message } ->
From!Message ,
loop ()
end.
chargen
%%%-----------------------------------------------------
%%% File : chargen.erl
%%% Author : Claes Wikstrom <klacke@erix.ericsson.se>
%%% Purpose :
%%% Created : 3 Nov 1998 by Claes Wikstrom <klacke@erix.
ericsson.se>
%%%-----------------------------------------------------
-module(chargen).
-author('klacke@erix.ericsson.se').
-export([start_link/0, start/1, loop0/1, worker/2]).
-define(PORTNO, 2019).

153
start_link() ->
start_link(?PORTNO).
start_link(P) ->
spawn_link(?MODULE, loop0, [P]).
loop0(Port) ->
case gen_tcp:listen(Port, [binary, {reuseaddr,
true},
{packet, 0}, {active, false}]) of
{ok, LSock} ->
spawn(?MODULE, worker, [self(), LSock]),
loop(LSock);
Other ->
io:format(«Can't listen to socket ~p~n», [Other])
end.
loop(S) ->
receive
next_worker ->
spawn_link(?MODULE, worker, [self(), S])
end,
loop(S).
worker(Server, LS) ->
case gen_tcp:accept(LS) of
{ok, Socket} ->
Server ! next_worker,
gen_chars(Socket, 32);
{error, Reason} ->
Server ! next_worker,
io:format(«Can't accept socket ~p~n»,
[Reason])
end.
gen_chars(Socket, Char) ->
Line = make_line(Char, 0),
case gen_tcp:send(Socket, Line) of
{error, Reason} -> exit(normal);
ok -> gen_chars(Socket, upchar(Char))
end.
make_line(Char, 70) ->
[10];
make_line(127, Num) ->
make_line(32, Num);
make_line(Char, Num) ->
[Char | make_line(Char+1, Num+1)].
upchar(Char) ->
if

154
Char + 70 > 127 ->
32 + (127 - Char);
true ->
Char + 70
end.
Parallaxis III
(* Parallel Computation of Prime Numbers *)
(* with SIEVE OF ERATHOSTHENES (Thomas Braunl'94) *)
MODULE prime ;
CONFIGURATION
list[2..200]; (* Use a list of PEs labelled 2..200 *)
CONNECTION; (* no connections needed here *)
VAR next_prime : INTEGER; (* scalar variable *)
removed : list OF BOOLEAN; (* vector variable *)

155
BEGIN
REPEAT
(* get next value from remaining list *)
next_prime := REDUCE.FIRST(DIM(list, 1));
(* print it *)
WriteInt(next_prime, 10); WriteLn;
(* remove all multiples in parallel *)
removed := DIM(list,1) MOD next_prime = 0
UNTIL removed
END prime.
CONFIGURATION
ring[12];
CONNECTION
c_wise : ring[i] -> ring[(i+1) mod 12];
cc _wise : ring[i] -> ring[(i-1) mod 12];
CONFIGURATION
grid[4][5];
CONNECTION
north : grid[i,j] -> grid[i-1, j];
south : grid[i,j] -> grid[i+1, j];
east : grid[i,j] -> grid[i, j+1];
west : grid[i,j] -> grid[i, j-1];
CONFIGURATION
torus[0 .. h-1], [0 .. w-1];
CONNECTION
north : grid[i,j] -> grid[(i-1) MOD h, j];
south : grid[i,j] -> grid[(i+1) MOD h, j];

156
east : grid[i,j] -> grid[i, (j+1) MOD w];
west : grid[i,j] -> grid[i, (j-1) MOD w];
CONFIGURATION
tree[1 .. 15];
CONNECTION
lchild : tree[i] <-> tree[2*i] : parent;
rchild : tree[i] <-> tree[2*i +1] : parent;
CONFIGURATION
tree[1 .. 15];
CONNECTION
child : tree[i] -> tree [2*i], tree[2*i + 1];
CONFIGURATION
hyper[0 .. 1],[0 .. 1],[0 .. 1],[0 .. 1];
CONNECTION
go[1] : hyper[i,j,k,l] -> hyper[(i+1) MOD 2,j,k,l];
go[2] : hyper[i,j,k,l] -> hyper[i,(j+1) MOD 2,k,l];
go[3] : hyper[i,j,k,l] -> hyper[i,j,(k+1) MOD 2,l];
go[4] : hyper[i,j,k,l] -> hyper[i,j,k,(l+1) MOD 2];
CONFIGURATION list[1 .. 8];

157
CONNECTION
next: list[i] -> {ODD(i)} list[i+1],
{EVEN(i)} list[i-1];
CONFIGURATION grid[1 .. 100],[1 .. 100];
CONNECTION one2many: grid[1,1] -> grid[1, 1..100];
CONFIGURATION grid[1 .. 100],[1 .. 100];
CONNECTION many2one: grid[i, j] -> grid[i, 1];
CONFIGURATION grid[1 .. 20],[1 .. 50];
tree[1 .. 1000];
CONFIGURATION grid[1 .. 20],[1 .. 50];
tree[1 .. 1000] = grid;
n
CONFIGURATION hyper[0 .. (2**n – 1)];
CONNECTION FOR k := 0 TO n – 1 DO
dir[k]: hyper[i] <-> {EVEN(i DIV 2**k)}
hyper[i + 2**k] :idir[k];
END;
*

158
VAR y: grid OF INTEGER;
A: grid OF ARRAY[1 .. 10] OF REAL;
B: ARRAY[1 .. 10] OF grid OF REAL;
VECTOR OF TYPE
Функции Описание
ID(conf) Векторнозначная функция, возвращающая номер процес-
DIM(conf, num) Векторнозначная функция, возвращающая номер процес-
LEN(conf) Целая функция, возвращающая количество процессорных
LEN(conf, num) Целая функция, возвращающая размер измерения num.
RANK(conf) Целая функция, возвращающая количество измерений в
LOWER(conf, num) Целая функция, возвращающая нижнюю границу измерения
UPPER(conf, num) Целая функция, возвращающая верхнюю границу измерения
ID2DIM(conf,num,dims) Превращает номер процессорных элементов в массивы
DIM2ID(conf, dims) Функция возвращает номера процессорных элементов, соот-
MOVE.dir(val) Передача данных по связи dir.
RECEIVE.dir(val) Прием данных val по связи dir
сорного элемента.
сорного элемента в измерении num.
элементов в конфигурации conf.
конфигурации conf.
num в конфигурации conf.
num в конфигурации conf.
dims.
ветствующие вектору массивов (или просто массиву) dims.

159
Функции Описание
SEND.dir(val, var) Посылка данных val по связи dir с сохранением в перемен-
REDUCE.func(val) Редуцирование вектора val в скалярное значение примене-
ной var.
нием функции func. func должна быть одной из предопределенной функций: SUM, PRODUCT, MAX, MIN, AND, OR,
FIRST, LAST, или пользовательской функцией с двумя
входными параметрами и возвращаемым значение одного и
то же типа.
VAR x: grid OF INTEGER;
s, t: INTEGER;
...
s := x <<12>>;
...
x<:3, 1:> := t;
...
MODULE cellular_automaton;
CONST n = 79; (* number of elements *)
m = (n+1) DIV 2; (* number of loops := middle *)
CONFIGURATION list [1..n];
CONNECTION left: list[i] <-> list[i-1] :right;
VAR i : INTEGER;
val: list OF BOOLEAN;
c : list OF ARRAY BOOLEAN OF CHAR;
(* = ARRAY[FALSE..TRUE] OF CHAR *)
BEGIN
val := ID(list) = m; (* Init *)
c[FALSE]:= « «;
c[TRUE] := «X»;
FOR i := 1 TO m DO
Write(c[val]);
val := MOVE.left(val) <> MOVE.right(val);
END;
END cellular_automaton.

160
ПРОГРАММИРОВАНИЕ НА MPI
#include <stdio.h>
#include <string.h>
#include «mpi.h»
/* Длина буфера сообщений */
#define BUF_LEN 256
int
main (int argc, char *argv[])
{
int my_rank; /* ранг текущего процесса */
int p; /* общее число процессов */
int source; /* ранг отправителя */
int dest; /* ранг получателя */
int tag =0; /* тег сообщений */
char message [BUF_LEN];/* буфер для сообщения */
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
