330 likes | 989 Views
제 12 장 병렬프로그래밍과 병렬 처리. 병렬 처리 소개 병렬 처리와 프로그래밍 언어 세마포어 모니터 메시지 전달 기법 실시간 언어. 병렬 처리. 순수 von Newmann 형 ( ~ in before chapter) 주어진 시간에는 한 문장 또는 하나의 Procedure 만 실행 현 시대의 문제 해결에 비 효율적 다중 프로세서 컴퓨터의 발전에 따라 , 새로운 언어 요구 비동기적 연산 , 다중 프로그래밍 (SW-base) 소개
E N D
제12장 병렬프로그래밍과 병렬 처리 • 병렬 처리 소개 • 병렬 처리와 프로그래밍 언어 • 세마포어 • 모니터 • 메시지 전달 기법 • 실시간 언어
병렬 처리 • 순수 von Newmann형 ( ~ in before chapter) • 주어진 시간에는 한 문장 또는하나의 Procedure만 실행 • 현 시대의 문제 해결에 비 효율적 • 다중프로세서 컴퓨터의 발전에 따라, 새로운 언어 요구 • 비동기적 연산, 다중 프로그래밍(SW-base) 소개 • 프로세서들의 병행으로 처리(예, 입출력 동안 CPU는 다른 프로세서 처리) 순차적으로 실행되어야 하는 일련의 연산들로 구성된 프로그램 • 병렬 처리(parallel processing – HW-base) 요구 • 다수의 프로세서들이 여러 개의 프로그램들 또는 한 프로그램의 분할된 부분들을 동시에 처리하는 기술 • 병렬 프로그래밍에 대한 연구 분야 병렬 프로그래밍 언어 자체에 대한 연구 - Ada, Occam, Concurrent Pascal 병렬 컴파일러에 관한 연구
병렬 처리 소개(1) • 하나의 프로세서에 의하여 순서대로 처리되는 일련의 명령어들과 데이터들의 흐름 • 컴퓨터 시스템 분류 - Flynn • 프로세서가 처리하는 명령어와 스트림에 따라 • SISD(Single-instruction Single-data) • SIMD(Single-instruction Multiple-data) • MISD(Multiple-instruction Single-data) • MIMD(Multiple-instruction Multiple-data) • 병렬 처리 컴퓨터는 SIMD와 MIMD 각자 제어 단위와 연산 단위 내장 비동기적이며, 자연스러운 모델 1개의 제어 프로세서와 n개의 프로세서들의 배열로 구성
병렬 처리 소개(2) • MIMD 컴퓨터 분류 - 프로세서들이 메모리를 사용하는 방식에 따라, • 공유 메모리 구조(shared-memory architecture) • 분산 메모리 구조(distributed-memory architecture) • 공유 메모리 구조 형태 • 공유 메모리 내의 공유변수를 통해 서로 메시지 통신 및 동기화 수행 • 프로세서 사용율을 균등하게 처리 가능 – 이용율 극대화 • 공유변수 접근의 제한(충돌) 발생 • 버스(하나의 통신로 제공), 크로스바 스위치, 다단계 상호망으로 해결 … 프로세서 프로세서 프로세서 주기억장소
병렬 처리 소개(3) • 분산 메모리 구조의 형태 • 각 프로세서들은 프로세싱 단위 보유(프로세서 + 메모리) • 프로세싱 단위들은 상호 연결망으로 연결, 이들간 메시지 전달 • 초기의 병렬 처리 컴퓨터 모델 • 확장성이 좋으나 메시지 전달 소요 시간 부하 • 사용되는 상호 연결망 • 선형 배열 구조 • 원형 구조 • 성형 구조 • 트리 구조 • 메시(mesh) 구조 • 시스톨릭(systolic) 구조 • 완전 연결(completely connected) 구조 • 코달 원형(chordal ring) 구조 • 하이퍼큐브(hypercube)
공유 메모리구조 분산 메모리 구조
병렬 처리와 프로그래밍 언어(1) • 병렬(parellel)Vs 병행(concurrent) • H/W 관련 용어 Vs 언어적 표현 동시 실행 • 무엇보다도, 병렬 가능 하려면, 병행성 표현이 가능한 언어가 전제조건 • 병행성의 표현 ① 문제가 지니고 있는 고유의 병행성을 자연스럽게 표현할 수 있어야… ② 효율적인 병행 기계어 프로그램으로 번역되어야… • 병렬 구조 모델 소개 (OS와비교하여 – PL은 OS보다 엄격) ① 언어들이 분산 모델을 가정하고 통신 기능을 제공 ② 공유 기억 장소 모델과 상호 배제를 위한 기능들을 사용
병렬 처리와 프로그래밍 언어(2) • 병렬처리의 예제(1) • 유한 버퍼 문제(the bounded buffer problem) • 2개의 프로세서가 계산과 IO 작업 동시 • 프로세서간 결과 저장 공간 그리고 통신과 동기화 요구됨 • 병렬 행렬 곱셈(parallel matrix multiplication) • 정수형 행렬 선언 VAR a,b,c:ARRAY[n,n] OF INTEGER // 이차원배열 FOR i := 1 TO n DO FOR j := 1 TO n DO c[i,j] := 0; FOR k := 1 TO n DO c[i,j] := c[i,j] + a[i,k] * b[k,j]; END; END; END; 수행시간 n3 But, n이되는 알고리즘 - 각각의 프로세서가 a,b,c 수행 즉, 병렬이 가능할려면 이와 같은 알고리즘을 구현할 수 있는 언어라야 한다.
병렬 처리와 프로그래밍 언어(3) • 반면, • 명시적인 언어 기능을 사용하지 않는 병렬 프로그래밍 • 묵시적으로 본래의 병렬성을 포함(함수, 논리, OOP언어) • 프로그래밍 언어에서 병렬 구조를 정의(컴파일 옵션) • 병렬 처리를 할 수 있는 라이브러리를 제공 #include <parallel/paralle.h> #define SIZE 100 #define NUMPROCS 10 shared int a[SIZE][SIZE], b[SIZE][SIZE], c[SIZE][SIZE]; void main(void) { int err; int multiply(); m_set_procs(NUMPROCS); m_fork(multiply); m_kill_procs(); } void multiply(void) { int i,j,k; for(i = m_get_myid(); i < SIZE; i += NUMPROCS) for(j = 0; j < SIZE; ++j) for(k = 0;k < SIZE; ++k) c[i][j] += a[i][k] * b[k][j]; } 프로세서 수 결정 프로세서 동기화 및 1개의 프로세서만 실행토록 지원 10개의 프로세서 생성 프로세서 인스턴ㅅ 번호 설정 인스턴스 번호에 따라 프로세서별로 분할됨
병렬 처리와 프로그래밍 언어(4) • 병렬처리 예제(2) - 프로세스 생성과 소멸기법 제공되어야… • 병렬 처리 지원을 위한 필요한 메커니즘 • Like as m_set_procs and m_fork라이브러리 프로시저 • 프로세스를 생성 방법 • 현 프로세스를 두 개 이상의 프로세스로 분리 사용. • 같은 프로그램의 사본 사용, 부모 / 자식 프로세스 • SIMD와유사하여 SPMD(S Program MD) 프로그래밍이라 함 • SIMD와 SPMD의 차이점 • 다른 세그먼트를 실행할 수 있고, 비 동기도 가능 • 하나의 코드 세그먼트가프로세스와 관련 되도록…. • 각각의 다른 프로세스는 다른 코드를 가짐(MPMD) • 전형적인 예(fork – join 모델) • 하나의프로세서는다수의 프로세서 생성(a fork : 세그먼트) • 부모 프로세서는 자식 프로세서를 기다림(a join) • But, unix의 fork-join은 SIMD성격, therefore, Just MPMD
병렬 처리와 프로그래밍 언어(5) 프로세서에 할당 적절한 코드 크기 • 병렬 처리를 위한 선택 방법 - 입상(granularity)크기에 따라, ① 명령어 수준의 병렬성- 작은 덩이, 프로세서 생성 유지 오버헤드 발생 ② 프로시저 수준의 병렬성 - 중간 덩이 ③ 프로그램 수준의 병렬성- 큰 덩이, 병렬성 부여 기회 소멸 • 반면, 프로세서 생성 방법과 관계없이, • 프로세스 생성자(부모)와피생성자(자식)간의 구분 가능해야 함 • 프로세스 생성 기법 고려 사항 • 자식 프로세스 수행 중 - 부모 프로세스 일시 중지 가능한가?, 또는 동시 실행 가능한가? • 기억 장소 공유 가능 • 부모 프로세스와 자식 프로세스 또는 자식 프로세스들 사이 • 표 12.1 사용 예 : 부모 프로세스 일시 중지되며, 전역 변수 a, b, c (shared 선언) – 모든 프로세스 공유
병렬 처리와 프로그래밍 언어(6) • 명령어 수준의 병렬성 • 주로 VHDL (hardware description language)에서택함 • 기본적으로 소자들은 병렬로 작동하기 때문 parbegin S1; S2; . . . Sn; parend (S1, S2, … Sn)은 병렬로 수행되며, 이들이 수행되는 동안 부모프로세서는 일시 정지되며, Si 프로세서들은 지역변수를 제외한 모든 변수를 공유함 for i := 1 to n do parallel begin for j := 1 to n dobegin c[i,j] := 0; for k := 1 to n do begin c[i,j] := c[i,j] + a[i,k] * b[k,j]; end; end; end; 병렬 순환으로 확장한 개념
병렬 처리와 프로그래밍 언어(7) • 프로시저 수준의 병렬성 • 프로세서를 생성하고 소멸하는 방법에서, • 하나의 프로시저를 하나의 프로세스와 대응시켜 실행 • 생성 소멸 기법 ( p : 프로시저, x : 프로세스) 1) 2) 프로시저와 프로세서 결합 선언문 사용 (Ada언어) • X의 영역과 생성 종결 : 지역 변수와 유사 x := newprocess(p); . . . . . . killprocess(x); var x : process(p);
병렬 처리와 프로그래밍 언어(8) #define SIZE 100 #define NUMPROCS 10 int a[SIZE][SIZE], b[SIZE][SIZE], c[SIZE][SIZE]; void main(void) { int myid; for (myid = 0; myid < NUMPROC; ++myid ) if(fork( ) == 0) { multiply(myid); exit(0); } for (myid = 0; myid < NUMPROCS; ++myid) wait(0); /* code to output c goes here */ } void multiply(int myid) { int i,j,k; for( i=myid; i < SIZE; i += NUMPROCS) for ( j=0; j < SIZE; ++j) { c[i][j] = 0; for(k = 0; k<SIZE; ++k) c[i][j] += a[i][k] * b[k][j]; } } • 프로그램 수준의 병렬성 • 전체 프로그램이 하나의 프로세스와 대응(MPMD 방식) • 자신의 사본을 생성하여 새로운 자식 프로세스생성 • 예 : UNIX fork() 시스템 호출 • 호출 시점에 환경 상속 • fork() 반환 값으로 부모(n:번호), 자식(0) 프로세스 구별 • exit - 생성된 프로세스 종료 • wait - 프로세스 동기화, 이 때 부모 프로세스 일시 중지 NUMPROCS 수 만큼 자식 프로세서 생성 그리고 자식프로세서 수 만큼 wait Fork 구조(fork, exit, wait)를 나타내는 C코드 예
병렬 처리와 프로그래밍 언어(9) • 반면, • 앞서, PL의 병행 기법들이 소개되었지만, 병행 기능의 양상을 살피는 것이 PL Design에 유용 ① 병렬로 실행될 수 있는 코드 묶음을 한정 • 프로세스, 태스크, collateral절 ② 프로세스의 실행 시작을 기술하는 방법 ③ 공유 자료의 상호 배제를 보장하는 방법 (신호기, 모니터, 메시지) ④ 병행 프로그램들을 동기화 시킬 수 있는 수단 제공 • 모니터의 대기와신호(wait-signal) 연산, 그리고 Ada의 랑데뷰(rendezvous) ⑤ 프로세스에 우선 순위를 부여하는 방법 ⑥ 프로세스를 지정된 시간 동안 지연시키는 기법
세마포어(Semaphores) (1) • 임계구역(Critical Section, Region) • 프로세서들의 공유 변수들을참조하는 일련의 문장 • 해당 문장 실행 시 다른 태스크의 문장의 실행은 금지 됨 • 종료(Terminate) • 정해진시간내에 임계구역 실행을 항상 끝낸 프로세서 • 정당한 스케줄(Fair Scheduling) • 한프로세서가 어느 한정된 시간 내에 임계구역 실행 • If, 임의의 프로세서가 임계구역실행 시, 다른 프로세서는 임계구역을 실행할 수 없음-상호배제(Mutual Exclusion) 요구 • Dijkstra – semaphore(신호기) 개발 (ALGOL 68) • 하나의 Binary valued variable(이진 값) s를 공유 • So, semaphore s가선언되면, 두 연산 wait(s), signal(s) 허용 • Queue로 구현되며, fair scheduling 요구
세마포어(Semaphores) (2) 하나의 프로세서는 실행 중이거나, 실행되기를 기다리거나 실행되는 다른 프로세서에 의해 봉쇄된 상태를 갖는다. 어떤 프로세서 P가 신호기 S를 사용한다면, wait(s) : if s = 1 then s := 0 else프로세스 P를 큐에 저장 signal(s) : if queue empty then대기중인 프로세스 준비 else s:= 1 Mutual Exclusion Using a Binary Semaphore procedure READER begin . . . wait(mutex) DB에서 자료 읽음 signal(mutex) . . . end procedure WRITER begin . . . wait(mutex) DB에 기록 signal(mutex) . . . end
세마포어(Semaphores) (3) 표 12.4 세마포어를 이용하여 해결한 생산자-소비자 문제 ok := 0 ; fin := 1 procedure PRODUCER while입력할 레코드가 있으면 do wait(fin) 한 레코드를 버퍼에 채움 signal(ok) end procedure CONSUMER loop wait(ok) 버퍼에서 한 레코드를 읽어서 출력 signal(fin) 결과를 출력 repeat end
세마포어(Semaphores) (4) • 세마포어에 카운팅 신호기 – 발전된 세마포어, 다중 버퍼 사용 • Counting semaphore : ALGOL 68 (sema) • 선언문 : sema mutex, 다음 연산 제공 • Collateral 문 • 두 개 이상의 문장으로 구성된 리스트로서 ( , ) 로 분리되며, begin – end 또는 ( ) 로 쌓임 • 모든 문장이 종료되어야 완료됨 Down mutex : if mutex = 0 then 실행이 블록됨 else mutex := mutex – 1 Up mutex : mutex := mutex + 1, mutex 때문에 블록된 프로그램을 실행 재개 함 begin BEGIN S1, S2, … , Sn END S1 S2 … Sn end Algol 68의 collateral statement
세마포어(Semaphores) (5) • 병렬절(parallel clause) • Collateral문과 유사하나, par 예약어로 병렬절 표기 Begin int buffer[50] ; int I := 0, j := 0; sema numberin := level 0, openspots := level 50 ; par(do down openspots ; I := I mod 50 + 1 read(buffer[I]) ; up numberin ; od do down numberin ; j := j mod 50 + 1; print(buffer[j]) ; up openspots ; od) end Algol 68에서 해결한 생산자-소비자 문제 버퍼 안으로 자료 읽어 들임 버퍼에서 출력
모니터(Monitors) (1) • 공유 자료 접근 코드를 하나로 묶은 단위 프로그램 • 어느 주어진 시간에는 하나의 프로세스만이 모니터의 프로시저를 실행시킴 • Queue 구성 자동, wait – signal 연산(명령) • 소개된 언어 • Concurrent Pascal (Brinch Hansen), Modula (Wirth), Mesa (Xerox), CSP/K (Holt) – Concurrent SP/K • Syntax (SIMULA의 CLASS 비슷 추상 자료형 지원) • 세마포어 단점 • 임계구역 안에 하나 이상의 프로세서 존재 가능성 • 잘못된연산 또는 코딩(signal이 실수로 wait이면) • 컴파일러에 의한 신호기의 부적절한 초기화 발생 monitorname begin 이 모니터의 지역 자료 선언 프로시저들 선언 지역 자료 초기화 코드 end name 선언된 프로시저(P)를 호출하는 형식 name.P (실 매개변수들)
모니터(Monitors) (2), in CSP/K EXAMPLE: PROCEDURE OPTIONS(CONCURRENT) // 병행 프로시저 선언문 CRITICAL: MONITOR// 모니터 선언 ( monitor 내부에 Entry) DECLARE (SUM) BINARY FIXED; DO; SUM=0; // SUM은 지역변수, Monitor를 통해서만 접근 가능 END; COUNT: ENTRY; // Entry COUNT, SUM ++ SUM=SUM+1; END; WATCH: ENTRY; // Entry WATCH , SUM 출력및 초기화 PUT SKIP LIST(SUM); SUM=0; END; END CRITICAL; COUNTER: PROCESS; . . . CALL COUNT; // process counter 선언, COUNT entry call . . . END COUNTER; WATCHER: PROCESS; . . . CALL WATCH; // process watcher 선언, WATCH entry call . . . END WATCHER; END EXAMPLE; 주의 : 동일 모니터 내, 다른 모니터의 Entry 호출 금지 참고 : - 비 지역 변수 참조 발생(PL/I 영역규칙으로 인함) - FIFO 스케줄링
모니터(Monitors) (3) • Concurrent-Pascal(1) • 프로세스, 모니터, 클래스, init, delay(wait), continue(signal)문, queue 자료형 추가됨 • 프로세스(외부영역변수 상속불허, 전용변수인 지역변수만 접근함) 형식 • 모니터 형식 • entry 선언 procedure ( 상호 배제되면서 사용되어질 프로시저 ) type프로세스이름 = process (형식 매개 변수들) 변수, 상수, 자료형, 프로시저 선언문들; 몸체 end type모니터이름 = monitor (형식 매개 변수들) 공유 변수들, 지역 프로시저들, 진입점을 갖는 프로시저들 begin 초기화 코드 end procedure entry controldisk(var x: buffer)
Concurrent-Pascal의 생산자-소비자 문제 모니터(Monitors) (4) • type buffer = array (1..80) of char; • producer = process • var card : buffer • begin card(1) := ‘N’ • while card(1) <> ‘E’ do • begin read(card); spool(card); end; • end; • consumer = process • var line : buffer • begin line := ‘N’ • while line <> ‘E’ do • begin unspool(line); write(line); end; • end; • cbuffer = monitor • var pool : array(1..5) of buffer • front, read, nobuf, noful : interger • procedure entry spool(contents : buffer) • begin if noful = noful then delay; • pool(rear) := contents • rear := rear mod nobuf +1; • noful := noful +1; • continue // 대기 프로세서 실행 • end; • procedure entry unspool(contents : buffer) • begin if noful = 0 then delay; • contents := pool(front); • front := front mod nobuf +1; • noful := noful –1; • continue // 대기 프로세서 실행 • end; • begin front := 1; rear := 1; • nobuf := 5; // 버퍼의 총 개수 • noful := 0 // 채워진 버퍼의 개수 • end • var x: producer, y : consumer, z : cbuffer • begin • init x, y, z • end. // 프로세서, 모니터선언과 초기화 var X:(프로세스 이름) init X(실매개 변수) // 모니터 선언과 초기화 var p, q: 모니터 이름; init q(실매개변수들)
모니터(Monitors) (5) • 모니터 정리 • 병행 프로세스들이 자원을 액세스하지 못하도록 자원들의 집합 둘레에 벽을 만드는 기법 • 프로그래머에게 세 가지 설비를 제공 • 모니터 안에 정의된 프로시저를 호출하는 방법 • 외부에서의 다양한 호출에 대한 스케줄링 방법(Queue) • 모니터를 호출한 프로세스들의 대기와 실행 계속을 허용하는 기법 (wait-signal 또는 delay-continue문)
메시지 전달 기법(1) • H/W 발전, So, Processor들의 network 구축 가능 • 전용의 기억장소와 다중 프로세서 환경 • 중요 요소 : 동기화와 통신 • Monitors • 공용 기억장소에서 단일, 또는 다중 processor 환경에 적절 • Solutions • 분산형 병행처리언어 제시 • Distributed Processes(DP)언어(Brinch Hansen) • Communication Sequential Processes(CSP) 언어(Hoare) • DP, CSP 특징 • 병행 프로그램의 실행 단위 : 프로세스 선택 • 프로세스들 간의 통신 : 메시지 • 느슨히 결합된 분산 네트워크(loosely coupled distributed network)
메시지 전달 기법(2) • CSP • action : 메시지 형태 지정 (형태, 수신할 타입 포함) • 다소 논쟁이 발생, 이후 사용되지 않음 • DP : Brinch-Hansen process P Q ! action(x) // Q 프로세서에게메시지 송신 ……… process Q P ? action(y) // P 프로세스로부터 메시지 수신 ……… • call Q.R(input # output) // 프로세스 Q의 프로시저 R를 실행 // • input : 실입력 매개 변수 • output : 프로세스 Q에서 값을 받기 위해 사용된 매개 변수 procedure R(입력매개변수들 # 출력매개변수들) // Q에서 프로시저 R선언
메시지 전달 기법(3) • 동기화 문제 • 차이점 • 송신 P는 수신 P가 준비되기를 기다림 • 이 후 각자 수행 – CSP, Ada • 수신 P의 해당 procedure를 실행할 때까지 대기 – DP • 유사점 • Non-deterministic 지원 위해 보호 명령어(Guarded command) 사용 • CSP 프로세스 선언 • 보호 조건을 사용할 수 있는 문장 택일 명령문(alternative command) 반복 명령문(repetitive command) [p :: commands | q :: commands] - ‘|’ : p, q 프로세스, 병행 수행 가능
메시지 전달 기법(3) • CSP 택일 명령문 • CSP 반복 명령문(*) • DP의 비 결정 해결 Guard 문 • [ x > 0 y := +1 | x < 0 y := -1 | x=0 y := 0 ] • // 3가지 보호 조건에 따라 y에 x의 부호가 배정 i := 1; *[ i <= n; A(i) 0 A(i) := b(i) / A(i) ] - i가 1~n까지 배열 A(i)가 0인 경우를 제외한 모든 A(i)의 요소들을 B(i)/A(i)로 배정 • when B1 : S1 | B2 : S2 | . . . End • // 조건이참인 것이 있을 때까지 기다림 • cycle B1 : S1 | B2 : S2 | . . . End • // B1 - Bn의 조건 중 하나 이상이 참인 경우 when문과 같은 실행을 무한 반복
실시간언어 // 시간 지연과 관련 // loop -- 수행할 코드 delay 4.0; end loop ; • 특징 • H/W적인 interrupt에실시간 반응되어야 함 • 저급 프로그래밍 실력 겸비 • 예) 화학적인 반응에 따른 안전 문제 등. • 고려사항 • 병행처리 + 시간적인 요소 • 프로세스간 우선순위 허락 // 시간 지연과 관련 // start_time := clock; loop -- 수행할 코드 start_time := start_time + 4.0; delay start_time – clock; end loop ; // 인터럽트 task specipication // tasktop_interrupt_handler is entry pressure_warning; for pressure_warnning use at allocated_location; end top_interrupt_handler; // task body // taskbody top_interrupt_handler is begin accept pressure_warning; ---적절한 행위 end top_interrupt_handler;