5월, 2017의 게시물 표시

[Directive] critical

병렬프로그래밍에서 특별한 언급이 없으면, 모든 쓰레드들은 독립적이지 않은 공통변수들을 가지게 됩니다. 그래서 공통변수를 업데이트 시키는 동안에 다른 쓰레드에서 중간에 업데이트 하는 경우도 있습니다. 이러한 상황은 정확화지 않은 결과를 불러오게 됩니다. 그래서 공통변수가 업데이트 되는동안, 변하지 않도록 보호를 해주어야 합니다. atomic과 critical 디렉티브가 이러한 역할을 합니다. atomic 은 간단한 사칙연산이나 논리사칙연산에 대해서 보호해주는 역할을 하며, critical 디렉티브는 이를 포함한 좀더 범용적인 상황에서 보호를 해줍니다. critical 디렉티브 예제를 살펴봅시다. [Fortran 90] program Console     implicit none     !Variables     integer i     real max     parameter SIZE = 10     real :: a(SIZE)         do i=1,SIZE         call RANDOM_NUMBER(a(i))         write(*,"(E10.5)"), a(i)     end do         max = a(1)     !$omp parallel do num_threads(4)     do i=2, SIZE         if (a(i) > max) then             !$omp critical             ! compare a[i] and max again because max               ! could have been changed by another thread after               ! the comparison outside the critical section             if (a(i) > max) then                 max = a(i)             end if       

[Directive] single, master

OpenMP 페러렐코딩 중간에 단일 코어로 계산해야하는 경우 single과 master 디렉티브들이 단일코어로만 계산하도록 명령을 내립니다. 하지만 single은 배정된 쓰레드가 실행을 하는 동안 나머지 쓰레드들은 대기상태로 있는 반면, master는 나머지 쓰레드들은 멈추지 않고 바로 다음 블럭으로 가서 다음 블럭의 업무를 수행합니다. 먼저 single로 작성된 코드 예제를 살펴보면 다음과 같습니다. [Fortran 90]     program Console     implicit none     !Variables     integer i         !$omp parallel private(i)     !$omp single     do i=1,5         print *, "Hello World from single"     end do     !$omp end single     !implicit barrier     print *, "Hello World"     !$omp end parallel     read *     end program Console [Output]  Hello World from single  Hello World from single  Hello World from single  Hello World from single  Hello World from single  Hello World  Hello World  Hello World  Hello World single 블럭에서는 문자를 출력하는 작업을 반복적으로 하도록 지시 하였습니다. 이후 single 블럭 다음에는 각각의 쓰레드들에게 문자를 출력하는 작업을 지시했습니다. 결과를 보면 이 실행은 single 블럭이 끝나기 전까지는 수행되지 않았음을 알 수 있습니다. single 디렉티브가 끝나는 지점에 "implicit barrier"가 있음을 알 수 있습

[Directive] sections

OpenMP에는 다양한 Directive들이 있는데, 이글에서는 sections 라는 directive를 소개하도록 하겠습니다. sections는 블럭으로 나누어진 코드들을 하나씩 쓰레드를 분산 시켜서 실행시키는 명령문 입니다. 블럭은 section 이라는 명령어로 구분하며 처음부분과 마지막 부분에는 쓰지 않아도 됩니다. [Fortran 90]     program Console     implicit none     !Variables     integer thr_num     integer omp_get_thread_num         !$omp parallel sections num_threads(4) private(thr_num)     thr_num = omp_get_thread_num()     write(*,"(A17,I2)"), "Hello from thread ", thr_num     !$omp section     thr_num = omp_get_thread_num()     write(*,"(A17,I2)"), "Hello from thread ", thr_num        !$omp section     thr_num = omp_get_thread_num()     write(*,"(A17,I2)"), "Hello from thread ", thr_num        !$omp section     thr_num = omp_get_thread_num()     write(*,"(A17,I2)"), "Hello from thread ", thr_num        !$omp end parallel sections     end program Console [Output] Hello from thread 0 Hello from thread 1 Hel

[Directive] do/for

알고리즘을 작성하면서, 가장 많이 쓰는 기능중 하나가 반복문 입니다. 반복문에 대해서 병렬화 작업을 해주는 OpenMP Directive는 do/for 입니다. Fortran 에서는 Do이고, C/C++에서는 for Directive 입니다. [Directive] do 를 이용하여서, 1에서 10까지의 덧셈을 병렬로 실행하는 포트란 코드는 다음과 같습니다. [Fortran 90] ! omp_parallel.f90 ! compile with: /openmp         program Console     implicit none     !Variables     parameter NUM_THREADS = 4     parameter NUM_START = 1     parameter NUM_END = 10     integer :: i, nRet, nSum, nStart, nEnd     integer :: nThreads, nTmp     integer :: uTmp     integer :: nSumCalc     integer :: omp_get_num_threads         nRet = 0     nSum = 0     nStart = NUM_START     nEnd = NUM_END     nThreads = 0     nTmp = nStart + nEnd     uTmp = (abs(nStart - nEnd) + 1) * abs(nTmp) / 2     nSumCalc = uTmp         if (nTmp < 0) then         nSumCalc = -nSumCalc     end if         call omp_set_num_threads(NUM_THREADS)         !$omp parallel default(none) private(i) shared(nSum, nThreads, nStart, nEnd)     !$omp master     nThrea

[Directive] parallel

 OpenMP는 공유메모리 병렬라이브러리로서 현재 표준병렬 라이브러리로서 자리매김 하고 있습니다. OpenMP의 구문은 Directive와 Clause로 구성되어 있습니다. 오늘은 Directive중에서 가장 많이 쓰이는 parallel Directive를 살표보고자 합니다. parallel Directive는 쓰레딩을 실행시키는 명령어로서 보통 병렬프로그래밍 시작할 때, 처음 부분에 쓰입니다. Fortran90으로는 다음과 같이 쓰여집니다. [Fortran90 Code]     program Console     implicit none     !Start OpenMP threading     !$omp parallel     write(*, "(A11)") "Hello World"     !$omp end parallel     end program Console [Output] Hello World Hello World Hello World Hello World 제가 사용하고 있는 컴퓨터에서는 4개의 코어가 있으므로, 4개의 결과가 나옵니다. parallel Directive에 Clause를 추가하여서 상세 옵션들을 조절 할 수 있습니다. 예를 들어  num_threads를 이용하여서, 다음과 같이 쓰레딩의 횟수를 조절 해 줄 수 있습니다. [Fortran90 Code]     program Console     implicit none     !Start OpenMP threading     !$omp parallel num_threads(3)     write(*, "(A11)") "Hello World"     !$omp end parallel     end program Console [Output] Hello World Hello World Hello World 위 예제에서는 3개의 쓰레드를 생성하였습니다. Clause

OpenMP 구문 구조

1944년 컴퓨터가 처음 출현하고난 후 하드웨어의 발전은 계속해서 거듭났습니다. 하지만 CPU는 쿨럭을 높일수록 발열이 점차 심해져서, 발전에 한계가 있었습니다. 이러한 문제점을 해결하기 위해서, CPU는 멀티코어의 방향으로 발전해 나갔습니다. 멀티코어에 따라서 프로그래밍에서도 코드 병렬화가 필요했습니다. 그러던중 1997년 OpenMP 아키텍처 리뷰보드는 최초의 API규격인 포트란 1.0용 병렬라이브러리를 출시했습니다. 이 후 2002년에는 C/C++용으로도 출시가 되었으며 인기가 많아지면서, 병렬컴퓨팅에서 표준적인 라이브러리중 하나가 되었습니다. 오늘 소개할 것은 바로 이 OpenMP의 구문 구조에 대해서 살펴 보도록 하겠습니다. OpenMP의 구문은 OpenMP의 시작과 끝을 알리는 부분들과 Directives 그리고 Clauses 로 나뉘어져있습니다. [Fortran OpenMP] !$OMP [Directives] [Clauses](optional)    .    . !$OMP END [Directives] [C/C++ OpenMP] #pragma omp [Directives] [Clauses](optional) {    .    . } 먼저, OpenMP의 시작을 알려주는 구문이 맨처음에 나와있습니다. 그리고 Directives 는 전체적인 방향을 결정하는 부분이고, 반드시 있어야됩니다. Clauses 는 옵션으로 넣어주는 부분이여서 세부사항을 조절 할 때, 이용하는 부분입니다. 마지막으로 OpenMP 코딩의 끝을 알려주는 구문을 적습니다. C의 경우에는 괄호로 범위를 설정합니다. 끝으로 Directive와 Clause는 다음과 같은 종류들이 있습니다. Directive Description atomic Specifies that a memory location that will be updated atomically. barrier Synchronizes all threads in a team; all thread

Bash에서 DropBox 파일다운

이미지
Bash 에서는 인터넷 링크 파일을 다운 받는 기능이 있는데, 대표적으로 wget 과 curl 이 있습니다. wget은 별도의 설치가 필요하지만, curl은 별도의 설치 없이 기본 기능에 내장되어 있습니다. 반면 wget은 경로의 구조까지 다운받을 수 있는 장점이 있습니다. 오늘은 이중에서 curl 을 이용한 다운 받는 방법을 알아보겠습니다. Leeui-MacBook-Pro:Desktop leejijin$ curl -O http://ftp.gnu.org/gnu/Licenses/fdl-1.1.txt    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                  Dload  Upload   Total   Spent    Left  Speed 100 18138  100 18138    0     0   5322      0  0:00:03  0:00:03 --:--:--  5322 Leeui-MacBook-Pro:Desktop leejijin$  명령어 curl -O [url] 은 url 주소의 파일의 이름을 그대로 해서 다운 받으라는 명령어 입니다. 이름을 지정해서 받고 싶다면, curl -o filename.ext [url] 명령어로 받습니다. DropBox의 파일 또한 url들을 생성해 줄 수 있습니다. 먼저 해당파일을 체크한 후 공유버튼을 누르면 링크 생성창이 나타납니다.  링크생성을 누른 후 링크표시를 하면 링크를 복사 할 수 있습니다. 링크를 복사하여 아래와 같이 명령어를 치면, 다운되는 것을 볼 수 있습니다.  드롭박스 링크는 Shortened URL 주소이므로 -L옵션을 붙혀줘야만 합니다. Leeui-MacBook-Pro:Desktop leejijin$ curl -L -o test.dmg https://www.dropbox.com/s/qwerkkdksee/te

모바일에서 AWS 접속

이미지
SSH 는 Secured Shell의 줄임말로서 암호화된 메시지를 전송하는 시스템입니다. 그러므로 우리를 안전하게 원격접속을 할 수 있도록 만들어줍니다. 특히 서버에 접속할 때 널리 쓰이는 방식중 하나입니다. 이번 포스트에서는 모바일 기기에서 AWS에 SSH 접속하는 방식에 대해서 다루도록 하겠습니다. 아이패드에서는 prompt 2 와 Termius 앱을 이용하여 접속을 할 수 있습니다. prompt 2 는 유료이며, Termius는 무료버전으로도 쓸 수 있습니다. 이 글에서는 prompt 2 기준으로 설명하겠습니다. 먼저 Prompt 앱을 처음 실행하면 다음과 같이 나옵니다. 먼저 일반적인 접속은 SSH 에 IP 나 도메인 주소를 입력하고, Port에서 22 를 입력합니다. 지정된 Username 과 Passward 를 입력하여 간단하게 연결 하면 됩니다. 아마존 웹서비스를 접속하기 위해서는 패스워드 부분에 보이는 열쇠아이콘을 클릭하면 다음과 같이 키를 추가하는 패널이 나타납니다. "+" >> Generate New Key 이름을 Awskey 으로 지정해주고, "Generate" 를 클릭하여 키를 생성합니다. "Copy Public Key" 를 눌러서 Key를 복사 합니다. AWS로그인 >> My Account >> Services >> EC2  NETWORK & SECURITY >> Key Pairs>>Import Key Pair  Key pair name 에 Awskey를 넣어주고, Public key contents에 복사한 Key를 붙여넣기 합니다. 그리고 Import 를 눌러서 Key Pair를 생성합니다. INSTANCES >> Instances >> Launch Instance U

Bash 기본 파일 명령어

Bash는 윈도우의 CMD와 같은 컴퓨터 명령어로서 리눅스에서 많이 사용되어져 왔습니다. 윈도우 10 에서도 지원하기 시작하면서 맥을 포함한 대부분의 운영체제에서 기본적으로 쓸수 있는 명령언어가 되었습니다. 이번 글에서는 Bash의 기본 명령어들을 알아보도록 하겠습니다. $ ls    현재 파일들의 리스트들을 보여줍니다. Leeui-MacBook-Pro:~ leejijin$ ls Applications Downloads Movies Projects intel Desktop Dropbox Music Public iterate.dat Documents Library Pictures Qt $ ls -F   파일들의 확장자까지 표시해줍니다. Leeui-MacBook-Pro:~ leejijin$ ls -F Applications/ Downloads/ Movies/ Projects/ intel/ Desktop/ Dropbox/ Music/ Public/ iterate.dat Documents/ Library/ Pictures/ Qt/ (디렉토리는 '/', 실행파일은 '*', 심볼릭 링크는 '@'가 나타남). $ ls -l   파일들의 상세정보까지 표시해줍니다. Leeui-MacBook-Pro:~ leejijin$ ls -l total 8 drwx------@  3 leejijin  staff   102  3 28 09:48 Applications drwx------+  5 leejijin  staff   170  5 21 14:41 Desktop drwx------+  3 leejijin  staff   102  3 18 21:02 Documents drwx------+  8 leejijin  staff   272  5 17 23:42 Downloads drwx------@

Fortran Basic

포트란 라이브러리는 수치연산에 특화된 언어로서 빠른 수치연산과 풍부한 수치라이브러리를 가지고 있습니다. 여러가지 버전의 포트란이 있고, 이번 블로그에서는 Fortran 90의 기본적인 문법에 대해서 살펴볼 것입니다. 먼저 메인 프로그램 작성과 텍스트 출력은 다음과 같습니다. Example 1     program Console     implicit none     ! Variables     ! Body of Console     print *, 'Hello World'     end program Console implicit none - 암묵적으로 선언되어 있는 변수들을 사용하지 않습니다.                    !  - 주석을 달 수 있습니다.           print *  - 출력하고 싶은 문자를 써주면 됩니다. 포트란은 다른 언어와 달리 프로그램 가장 앞부분에서 변수 선언을 합니다. 수치연산에 특화된 언어인 만큼 벡터와 행렬을 쉽게 선언해서 사용할 수 있는 부분이 돋보입니다. Example 2     program Console     implicit none     !Variables      integer :: i,j     double precision :: a     double precision, dimension :: N(2), M(2,3)     double precision, dimension(:), allocatable :: N_alloc     double precision, dimension(:,:), allocatable :: M_alloc     !Body of Console     i = 1     a = 1d0       N = (/1d0, 2d0/)     M = reshape((/1d0, 2d0, 3d0, 4d0, 5d0, 6d0/), (/2,3/))     ! [1 3 5]     ! [2 4 6]     allocate(N_