There is no default zmodem protocol support on amazon ec2 instance, so we need to install one manually (We use lrzsz as example here. You can get the latest version on lrzsz’s website). Follow these simple steps to install:

  1. wget http://ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz
  2. tar -xzvf lrzsz-0.12.20.tar.gz
  3. cd lrzsz-0.12.20
  4. ./configure –-prefix=/usr/local/lrzsz
  5. make
  6. sudo make install
  7. cd /usr/bin
  8. ln -s /usr/local/lrzsz/bin/lrz rz
  9. ln -s /usr/local/lrzsz/bin/lsz sz

now try running rz on your ec2 install, the file upload window should be shown :)

'연구개발 > AWS' 카테고리의 다른 글

ec2 metadata  (0) 2017.07.07
[AWS] EC2 Linux(Ubuntu) 계정 추가 & 설정  (0) 2017.06.22
아마존 클라우드 Ubuntu에서 한글 사용  (0) 2016.05.18
aws. instance. clone. 복제  (0) 2016.02.19
리눅스 시간 동기화  (0) 2015.11.06

제1장 OS의 개요

1.1 OS의 개념 및 종류

1.1.1 운영체제의 개념

     (1) 정의 - 제한된 컴퓨터의 각종 자원을 효율적으로 관리, 운영함으로써 사용자에게 최대의 편리

                성을 제공하고자 하는 인간과 컴퓨터 사이의 인터페이스를 위한 시스템 소프트웨어

     (2) 역할 - 사용자와 컴퓨터 시스템간의 인터페이스 정의

              - 사용자들간의 하드웨어의 공동사용         - 여러 사용자간의 자원 공유    

              - 자원의 효과적인 운영을 위한 스케쥴링     - 입출력에 대한 보조 역할      

              - 에러에 대한 처리                         - 사용자들간의 간섭 방지

              - 자원의 사용량 계산                       - 병렬 수행을 위한 편의 제공

              - 데이터에 대한 보안과 신속한 사용         - 통신 네트워크 관리

     (3) 목적

        1) 사용의 편리성 - 사용자로 하여금 컴퓨터의 하드웨어와 각종 정보를 효율적으로 관리하여 

                           컴퓨터를 보다 편리하게 사용할 수 있도록 제공

        2) 시스템 성능의 향상 - 성능의 최대 발휘를 목적으로 하며 다음의 기준으로 판단

           ① 처리능력(throughput) - 일정 단위 시간 동안 컴퓨터가 처리하는 작업의 양

           ② 응답시간(turn around time) - 한 작업을 처리할 때 입력으로부터 결과가 출력될 때까지

                                           의 경과 시간

           ③ 사용의 용이성(availability) - 사용자가 필요로하는 컴퓨터를 적절한 때에 얼마나 빨리 

                                          사용할 수 있도록 할 것인가

           ④ 신뢰도(reliability) - 컴퓨터가 올바로 작동되는가

     (4) 구성

        1) 제어 프로그램(control program)

           ① 감시 프로그램(supervisor program)

           ② 데이터 관리 프로그램(data management program)

           ③ 작업 제어 프로그램(job control program)

        2) 처리 프로그램(processing program)

           ① 언어 번역 프로그램(language translator program)

           ② 서비스 프로그램(service program)

           ③ 문제 프로그램(problem program)

     (5) 운영체제의 구조

        - 커널 : 인터럽트처리기, 디스패쳐, 프로세서 동기를 위한 기능 지원, H/W와 밀접하게 관련

        - 기억장치 관리기       - 입출력 시스템        - 파일 관리기

        - 단기 스케줄러 : 시스템 내 활성 큐 관리, CPU 관리, H/W와 무관

        - 자원관리기 : CPU를 제외한 다른 자원들을 관리

        - 장기 스케줄러 : 프로세서의 생성, 소멸, 제어를 담당

        - 명령어 해석기 : 사용자와 직접 대화, Shell 이라 부름


1.1.2 OS의 종류

     (1) 운영체제의 등장

         1) 1950년대 초 general motors사에서 IBM 701을 위한 최초의 운영체제를 개발하였으며 그 전에는 

            운영체제의 할 일이 사람에 의해서 직접 처리되었다.

         2) 특징(1950년대) - 일괄처리 시스템의 시작

                          - 작업제어 언어의 등장

     (2) 초기 운영체제 시스템

         - 한번에 하나의 작업만 수행하며 준비시간이 많이 걸린다

         - 장치 구동기 사용

     (3) 일괄처리 시스템(batch processing system)

         1) 1950년대 초기의 컴퓨터 처리방법 중 하나로 처리할 데이터를 일정량을 모아 한꺼번에 처리 

         2) 상주모니터(resident monitor) - 사용자가 한번에 한 작업씩 수행하던 것을 한 개의 batch로 묶어 

                                          자동 처리되게 한 OS

             * 상주모니터 구성요소

                - 인터럽트와 트랩 벡터, 장치 구동기, 작업의 순서화(대기 작업들), 제어카드 해석기

         3) 장점 - 시스템의 사용계획을 구체적으로 세워 능률적으로 사용할 수 있다

         4) 단점 - 반환시간이 늦고 프로그램의 오류수정 작업이 어려우며 CPU가 유휴상태로 되기 쉽다

             * 단점 보완 방법

               - 상주모니터, 오프라인 연산, 버퍼링, 스풀링

     (4) 다중 프로그래밍 시스템(multi programming system)

         - 하나의 중앙처리장치에 여러 개의 프로그램을 실행시킴으로써 짧은 시간에 많은 작업을 수행할 

           수 있게 하여 시스템의 효율을 높여 주는 것

         1) 고려사항 - CPU스케줄링, 기억장치관리기법, 장치스케줄링, 교착상태, 병행제어 및 보호문제

         2) 장점 - 다중 작업을 구현하므로 시스템의 효율이 높다

         3) 단점 - CPU의 유휴 시간이 길어진다

                 - 기억장치 관리 기법, CPU 스케쥴링 기법이 필요

     (5) 다중 처리 시스템(multi processing system) 기출96

         - 하나의 공용 기억장치를 통하여 두 개 이상의 프로세서를 제어하는 시스템

         - 공유된 주기억장치의 사용을 스케줄링 하는데 어려움이 존재

         1) 장점 - CPU를 여러 개 사용하여 작업속도와 신뢰성을 높일 수 있다

     (6) 시분할 시스템(time sharing system)

         - 한 대의 컴퓨터로 일정한 시간 내에 여러 가지 작업을 처리하는 방법

         1) 장점 - 여러 사람이 공동으로 CPU를 사용하며 여러 개의 프로그램을 기억장치에 적재

         2) 단점 - 운영체제를 복잡하게 한다

     (7) 실시간 시스템(real time system)

         - 처리 대상 데이터가 발생하는 즉시 처리하여 결과를 산출하는 방식

         1) 장점 - 사용자의 노력이 절감되고 처리시간이 단축되며 처리비용이 절감

         2) 단점 - 입출력 자료의 일시저장 및 대기가 필요하고 특정상태의 재현이 불가능

                 - 시스템에 장애가 발생할 때 단순한 재실행이 불가능

     (8) 분산처리 시스템(distributed processing system)

         - 지역적으로 분산되어 있는 여러 대의 컴퓨터가 프로세서 사이의 특별한 데이터 링크를 통해 교신

           하면서 한 조직 내의 동일한 업무를 수행하고 정보 교환을 위해 네트워크로 상호 결합된 시스템

         - 특징 : 자원공유, 신뢰성, 계산속도 증가, 통신


1.1.3 운영체제 관점

 * 운영체제에 대한 사용자의 관점은 시스템 프로그램 특히 명령어 해석기에 의해 결정

     (1) 프로세스 관점

         1) 운영체제를 프로세스의 상태를 변화시키는 프로그램의 일종으로 보는 관점

         2) 중앙처리장치는 한 시점에서 하나의 작업만 수행하므로 각 프로세스의 상태를 변화시켜야 한다

     (2) 자원 관리자 관점

         - 운영체제를 시스템 자원들을 관리하기 위해 설계된 프로그램의 집단이라고 보는 관점

         1) 프로세스 관리 기능 - 어느 작업에게 CPU를 할당할 것인가를 결정

         2) 기억장치 관리 기능 - 어느 프로세스에게 기억장치를 할당할 것인가를 결정

         3) 장치관리 기능 - 장치를 할당하는데 어떤 방법이 효율적인지를 결정

         4) 정보관리 기능 - 어느 작업에게 어떤 자원을 사용하도록 할 것인지를 결정

     (3) 계층구조 관점

         1) 계층 1 - 프로세서 관리

            : 동기화 및 프로세서의 스케쥴링을 위한 프로세서 관리를 담당

         2) 계층 2 - 기억장치 관리

            : 기억공간의 할당 및 회수 기능을 실행하는 기억장치 관리를 담당

         3) 계층 3 - 프로세스 관리

            : 프로세스의 생성, 제거, 프로세스간 메시지전달, 프로세스의 시작과 정지 담당

         4) 계층 4 - 주변장치 관리

            : 주변장치의 상태파악 및 입출력 장치의 스케쥴링을 하고 입출력에 대한 전반 사항 지시

         5) 계층 5 - 파일 및 데이터 관리

            : 파일 생성과 소멸, 파일 오픈과 닫기, 파일의 유지 및 관리 등을 담당

     (4) 하드웨어 확장 관점 - 운영체제를 하드웨어의 기능 확대라는 측면에서 보는 관점

     (5) 기능적 관점 - 운영체제를 시스템 구성원 중의 일부로 보는 관점

     (6) 작업제어 언어 관점


1.2 System Software의 종류

1.2.1 System Software의 개념

     (1) 정의 - 특정한 문제를 해결하기 위한 알고리즘을 하드웨어에 정의해 주는 명령문과 데이터를 가진 

                프로그램으로 구성

     (2) 특징 - 컴퓨터의 작동, 수행에 있어서 기본이 되며 하드웨어 환경을 직접 제어

              - 컴퓨터 제조회사나 시스템 프로그래머에 의해 작성


1.2.2 System Software의 종류

     (1) 매크로(macro) - 프로그램에서 동일한 코드가 반복되어 나타나는 경우 이를 매번 나열하기 보다

                         하나의 간단한 코드로 정의하여 사용하는 기법

     (2) 링커(linker)

         - 목적프로그램 안에서 다른 목적프로그램을 호출하거나 여러 목적 프로그램들이 하나의 데이터를 

           공동으로 이용할 수 있도록 각 모듈간의 호출 및 공동 데이터의 이용을 가능하게 해주는 시스템 

           프로그램

     (3) 로더(loader)

        1) 절대로더(absolute loader) - 기계어 코드 프로그램에서 미리 지정한 번지에 프로그램과 데이터를 

                                      로드 한다

        2) 상대로더(relocating loader) - 로드 과정에서 메모리의 적당한 영역을 찾아 로드


2장 프로세스 관리

2.1 프로세스의 개념

2.1.1 프로세스 기출95

     (1) 개요 - 시스템에서 진행 중에 있는 모든 활동을 의미

     (2) 정의 - 현재 실행중이거나 곧 실행이 가능한 PCB를 가진 프로그램

              - 비동기적 행위, 순차적 실행, 능동적 개체, 수행중의 작업

              - 목적 또는 결과에 따라 발생되는 사건들의 과정

              - 지정된 결과를 얻기 위한 일련의 계통적 동작

              - 프로세스가 할당하는 개체로서 디스패치가 가능한 단위


2.1.2 순차 프로세스   - 의미 : 현재 실행중인 프로세스


2.1.3 프로세스의 상태

     (1) 프로세스 상태도

          보류(pending) → 준비(ready) ← 대기(blocked)

                                ↓↑      ↑

                                실행(running)

                                     ↓

                                완료(terminate)

     (2) 프로세스 상태

         1) 보류상태(pending) - 작업이 제출되어 스풀공간인 디스크에 수록되어 있는 상태

         2) 준비상태(ready)

            - CPU를 할당받을 수 있는 상태로서 CPU가 프로세스 자신을 처리해 주기를 기다리고 있는 것

         3) 실행상태(running)

             - 프로세스가 CPU를 차지하고 있는 상태로서 CPU에 의해 프로세스를 수행하고 있는 것

             - 부모 프로세스는 모든 자식 프로세스들이 종료될 때까지 기다린다

         4) 대기상태(blocked)

             - 프로세스가 CPU를 차지하고 실행되다가 입출력 처리와 같은 사건이 발생하게 되면 CPU를 

               양도하고 입출력 처리가 완료될 때까지 대기 큐에서 대기하고 있는 상태

         5) 완료상태(terminated)

             - 프로세스가 CPU를 할당받아 주어진 시간 내에 수행을 종료한 상태

             - 문장이 실행을 마쳤을 때 부모 프로세스에게 실행 결과를 돌려준다

     (3) 프로세스의 상태 전환 기출94

         1) 준비상태 -> 실행상태 : dispatch

            - 준비 상태의 프로세스들 중에서 우선순위가 가장 높은 프로세스를 선정하여 CPU를 할당함으

              로써 실행상태로 전환

         2) 실행상태 -> 준비상태 : time runout(할당시간 초과)

            - CPU의 지정된 할당 시간을 모두 사용한 프로세스는 다른 프로세스를 위해 다시 준비 상태로 

              되돌아간다

         3) 실행상태 -> 대기상태 : block

            - 실행중인 프로세스가 입출력 명령을 만나면 인터럽트가 발생하여 입출력 전용 프로세서에게 

              CPU를 양도하고 자신은 대기 상태로 전환 

         4) 대기상태 -> 준비상태 : wake up

            - 입출력 완료를 기다리다 입출력 완료 신호가 들어오면 대기중인 프로세스는 준비 상태로 전환


2.1.4 프로세스 제어블록(PCB)

     - 운영체제에 프로세스에 대한 중요한 정보를 제공해 주는 자료구조 테이블

     (1) PCB 수록 내용 기출94 기출96

         1) 프로세스 상태 - 보류, 실행, 준비, 대기, 정지 등의 상태

         2) 프로세스 번호 - 프로세스의 고유 번호

         3) 프로그램 카운터 - 프로세스가 다음에 실행할 명령어의 주소

         4) 레지스터 - 누산기, 인덱스레지스터, 스택 레지스터 등 범용레지스터와 상태코드 정보

         5) 기억장치 관리정보 - 경계 레지스터나 페이지 테이블들을 포함

         6) 계정 정보(회계정보) - CPU가 사용된 시간량, 시간의 범위, 계정번호, 작업 또는 레지스터 번호

         7) 입출력 상태 정보 - 입출력 요구들, 입출력 장치들과 개방된 파일 목록등

     (2) PCB의 관리

       - 프로세스 생성시에 만들어지며 모든 프로세스는 각각 고유한 PCB를 가지게 되고 수행이 완료된 

         프로세스인 경우에는 해당 PCB도 함께 삭제된다


2.1.5 프로세스 스케줄러의 종류 기출96

     (1) 장기 스케줄러(작업 스케쥴러)

         - 모든 job의 상태 파악, 다음에 수행될 job 선택, 시스템 자원 분배

         - 디스크 공간에 제출된 프로세스들을 선택하여 주기억 장치로 적재

         - 실행 간격이 비교적 크기 때문에 다음에 실행할 적절한 프로세스를 선택하는 시간을 더 사용해도 

           된다, 처리될 작업 결정, 다중 프로그래밍의 정도를 결정

     (2) 단기 스케쥴러(CPU스케쥴러)

         - 실행 준비가 되어있는 프로세스들 중에서 한 프로세스를 선택하여 CPU를 할당

         - 프로세스들간에 CPU를 자주 선택하기 때문에 수행 빈도수가 많고 각 프로세스의 CPU 할당 시간

           을 적게 한다면 더욱 자주 수행될 것이다, 주기억장치 내 작업들 중 실행작업 선택

     (3) 중기 스케쥴러

         - 기억장치에서 CPU를 경쟁하는 프로세스들의 수를 줄여서 다중 프로그래밍의 정도를 완화하는 것


2.1.6 프로세스의 종류

     (1) 독립적 프로세스(independent process)

         - 한 프로세스가 실행되면 다른 프로세스에 영향을 주거나 받지 않는 프로세스

         1) 프로세스가 독립적이므로 타 프로세스에 의한 공유가 없다

         2) 동일 입력은 동일한 결과를 갖는다

         3) 실행결과는 입력에 의해서만 결정된다

         4) 안정적으로 중단, 재실행될 수 있다

     (2) 유기적 프로세스(cooperating process)

         - 다른 프로세스와 데이터를 공유함으로써 영향을 주고받는 프로세스를 말한다

         1) 프로세스를 공유한다

         2) 실행결과는 입력뿐 아니라 상대적 실행순서에 의존한다

         3) 동일한 입력이라도 실행결과는 매번 다를 수 있다


2.2 병행 프로세스

2.2.1 병행 프로세스의 개요

  - 의미 : PCB를 가진 두 개 이상의 프로그램이 각각의 프로세스를 형성하여 동시에 수행


2.2.2 병행 프로세스에서 사용되는 주요 개념

     (1) 경쟁조건(race condition)

         - 공유메모리 : 함께 동작하는 프로세스들은 종종 메모리를 공유함

         - 경쟁 조건 : 2개 이상의 프로세스들이 공유 메모리에 읽기/쓰기를 하고, 그 결과가 어떤 프로세스

                       에 언제 실행되느냐에 따라 달라질 수 있는 상황

     (2) 상호배제(mutual exclusion)

         - 경쟁조건을 피하기 위한 방법

         - 상호배제 : 한 프로세스가 공유 메모리 혹은 공유 파일을 사용하고 있을 때 다른 프로세스들이 

                      사용하지 못하도록 배제시키는 제어기법 

                   or 두 프로세스가 하나의 자원을 동시에 점유할 수 없도록 조절하여 순차적으로 사용할 

                      수 있도록 하는 것(=상호보완)

     (3) 임계영역(critical section) 기출94

         - 임계영역 : 공유 메모리가 참조되는 프로그램의 부분

              or 두 프로세스가 한 버퍼에 있는 데이터를 동시에 접근하여 읽기/쓰기를 하고자 할 때의 버퍼 

         - 시간 종속 오류를 다루는 최초의 고급 수준 언어구조

           * 시간 종속 오류 : 프로세스들이 임의적으로 변수들을 공유할 때, 특정 순서로 실행될 때 발생

         - 임계영역 문제

            : 프로세스들이 서로 유기적으로 사용해야 하는 프로토콜을 설계

            : 각 프로세스는 그 임계구역에 들어갈 수 있는지의 여부를 미리 요청

            : 해결 ; 동기화 장치 또는 세마포어

         - 수행 순서를 잘 조절하여 2개 이상의 프로세스가 동시에 임계영역에 들어가지 않도록 한다면 

           경쟁 조건을 피할 수 있다

         - 상호배제를 위한 4가지 요구조건

           ① 상호배제조건 : 두개 이상의 프로세스들이 동시에 임계영역에 있어서는 안됨

           ② 진행조건 : 임계구역 바깥에 있는 프로세스가 다른 프로세스의 임계구역 진입을 막아서는 안됨

           ③ 한계대기조건 : 어떤 프로세스도 임계구역으로 들어가는 것이 무한정 연기되어서는 안됨

           ④ 프로세스들의 상대적인 속도에 대해서는 어떠한 가정도 하지 않는다


2.2.3 병행 프로세스의 문제점

     (1) 동기화(synchronization)

         - 두 프로세스가 한 기능을 사용할 때 상호배제가 이루어지도록 공동 협력하여 사용하는 것

     (2) 결과의 동일성 문제(determinancy)

         - 여러 프로세스가 동시에 수행될 때 각 프로세스의 수행결과는 수행순서와 시간에 관계없이 항상

           같아야 함

     (3) 의사소통 문제(communication)

         - 프로세스 사이의 데이터 교환에 관한 문제로서 일반적으로 메시지 전달 방법을 이용하여 데이터

           의 송수신을 확인

     (4) 외부 스케줄(explicit schedule)

         - 외부에서 프로그래머가 프로그램의 개발, 운영체제의 개발을 통하여 직접 해결할 수 있도록 하는 

           문제

     (5) 교착상태 문제(dead lock)

         - 상호배제와 동기화문제를 해결하지 못하여 프로세스들이 아무런 작업도 수행할 수 없도록 되는 

           문제

     (6) 동시처리 문제(concurrent processing)

         - 프로그래머가 직접 언어를 통하여 병행처리가 가능하도록 프로그래밍하는 것


2.2.4 세마포어(semaphore)

     (1) 세마포어의 개요 기출95 기출96

         1) 세마포어란 ?

            - 복잡한 문제에 있어서 상호배제를 해결하기 위한 동기화 도구

            - 신호기라는 뜻으로 각 프로세서에 제어신호를 전달하여 순차적으로 진행하기 위한 동기화구현

            - Dijkstra-데커의 알고리즘을 n개의 프로세스로 확장하여 상호배제 문제를 소프트웨어로 해결

         2) 세마포어의 사용

            - n개의 프로세스 임계구역 문제를 다루는데 사용

            - 여러 가지 동기화 문제를 해결하는데 사용

     (2) 표준연산

         - 세마포어 S는 표준단위연산 P(wait)와 V(signal)에 의해서만 접근 가능한 변수

         1) P(wait) 연산 : 프로세스를 대기상태로 전환하는 wait 연산을 수행

            # s.wait():

                 if (s.value > 0)  s.value--;

                 else 현재의 프로세스를 s.list에서 기다린다

         2) V(signal) 연산 : 프로세스에게 wake up 신호를 전달하는 signal 연산을 수행

            # s.signal():

                 if (1개 이상의 프로세스가 s에서 대기중이면)  그 중 1개 프로세스 수행

                 else s.value++;

         3) wait와 signal 연산이 세마포어 변수를 수정하는 것은 개별적으로 수행되므로 한 프로세스가 

            세마포어 변수 s를 수정 하면 다른 프로세스는 동일 변수 s에 대해 수정할 수 없다

     (3) 세마포어 응용

         1) 세마포어를 이용한 상호배제의 구현

            - 단지 세마포어 변수의 값을 1로 주고 임계영역에 들어가기 전에 wait를, 나올 때 signal을 호출

              하기만 하면 된다

         2) 세마포어를 이용한 동기화

            - block/wakeup 프로토콜 : 한 프로세스가 입출력을 요구하면 입출력이 끝날 때까지 그

              프로세스는 블록 상태가 되는데 이때 다른 프로세스는 이 블록된 프로세스를 깨워 줌

         3) 세마포어를 이용한 생산자 소비자 문제

            - 생산자는 소비자의 버퍼가 비었는지를 기다리고 소비자는 생산자의 버퍼가 채워졌는지를 

              기다림


2.2.5 모니터(monitor)

     - 상호배제에 대한 문제를 확실히 해결하여 여러 프로세스들이 자원을 안전하고 효과적으로 공유 할 수 

       있도록 한 기법

     (1) 목적 : 동기화를 자동적으로 제공하기 위함

     (2) 특징

         1) 모니터는 상호배제를 엄격하게 실시되어 한 순간에 하나의 프로세스만 모니터 내에서 수행

         2) 순차적으로만 사용할 수 있는 공유자원을 할당하는데 사용된다

         3) 데이터, 프로시저를 포함하는 병행성 구조

         4) 정보의 은폐(information hiding) 기법 - 모니터내부의 변수는 모니터 내부에서만 접근가능

         5) 모니터는 프로세스들이 추상 자료형을 안전하고 효과적으로 공유할 수 있게 함 


2.2.6 프로세스간 통신

     (1) 통신기법 기출94 기출95

         1) 공유 기억장치 기법(shared memory)

            - 통신하는 프로세스간에 기억장치 공간의 일부를 공유하도록 한다.

            - 통신 제공의 책임은 프로그래머에게 달려 있고, 운영체제는 단지 공유 기억장소만 제공

         2) 메시지 시스템 방법

            - 프로세스가 공유 변수에 의존하지 않고도 메시지를 이용하여 서로 통신할 수 있다.

            - 메시지를 관리, 전달하는 책임은 운영체제에 있다.

            - 일반적으로 send 와 receive 두 개의 연산을 제공한다.

            - 발생 가능한 예외적 상황 : 프로세스 종료, 메시지 상실, 메시지 혼합

            - 프로세스에 의해 보내지는 메시지 형태 : 고정크기, 가변크기, 타입을 가진 메시지

     (2) 명명(naming)

         1) 직접 통신 링크

            - 메시지를 주고받기를 원하는 프로세스가 수신자나 송신자의 이름을 명시적으로 표현해야 함

            - 통신을 원하는 프로세스 쌍 사이에는 자동으로 링크가 설정됨

            - 프로세스는 통신하는 상대 프로세스의 고유 이름만 알면 된다.

            - 링크는 두 프로세스와 관계하고 양방향성이다.

            - 어드레싱면에서 대칭적이고 일대일 통신이다.

            - 안정성과 신뢰성이 높다.

         2) 간접 통신 링크

            - 우편함을 통하여 메시지를 주고받을 수 있다.

            - 각 우편함은 메시지를 구별할 수 있는 유일한 이름을 갖는다.

            - 두 개의 프로세스는 공유 우편함을 갖고 있을 때에만 링크가 성립하여 통신이 가능하다.

            - 각 프로세스 쌍 사이에, 하나의 우편함에 관계되는 여러 개의 서로 다른 링크가 있을 수 있다.

            - 링크는 단방향 또는 양방향일 수 있다.


2.3 교착상태(Deadlock)

2.3.1 교착상태의 개요 기출95

     (1) 정의 

         1) 하나 또는 둘 이상의 프로세스가 더 이상 계속할 수 없는 어떤 특정 사건(자원의 할당과 해제)을 

            기다리고 있는 상태

         2) 둘 이상의 서로 다른 프로세스가 요구한 자원을 할당받아 점유하고 있으면서 상호간에 상대방 

            프로세스가 가지고 있는 자원을 요구하는 경우

     (2) 발생 예

         - 프로세스 1은 자원 1을 가지고 있으면서 자원 2를 요구하고, 프로세스 2는 자원 2를 가지고

           있으면서 자원 1을 요구하는 상태

     (3) 스풀링 시스템에서 교착상태

         1) 현재 수행중인 여러 작업이 인쇄할 행을 만들어 스풀링 파일로 보내고 있는 도중 이미 스풀링 

            파일 공간이 차버린 경우

         2) 교착상태 해결방법

            - 예상 필요 공간보다 많은 스풀링 파일 공간을 할당

            - 스풀링 파일이 일정한 포화 임계치를 넘지 못하도록 억제

     (4) 무한연기(infinite postpoment)

         1) 정의 - 여러 다른 프로세스들이 시스템에서 스케쥴링되어 처리되는 동안 한 특정 프로세스의

                   스케쥴링이 무기한으로 연기될 수 잇는 현상

         2) 발생원인 - 시스템(운영체제)의 편중된 자원 할당 정책 때문

         3) 노화(aging) 기법 - 프로세스가 자원을 기다리고 있는 시간에 비례하여 우선순위를 부여 기출95

  * 기아상태(starvation)

     - 자원 선점을 이용하여 교착상태를 제거하는데 있어서 희생자 선택을 할 때 동일한 프로세스가 매번

       선택되어 지정된 작업을 결코 완료할 수 없는 경우.


    # 무한연기와 교착상태의 비교

      

     (5) 자원의 종류

         1) 선점형 자원(preemptive resource)

            - 자원이 어떤 프로세스에게 할당되면 도중에 빼앗기는 경우

            - CPU나 주기억 장치

         2) 비선점형 자원(non-preemptive resource)

            - 일단 그 자원이 어떤 프로세스에게 할당되면 도중에 빼앗기지 않는 경우

            - 디스크, 테이프

         3) 전용 자원

            - 디스크나 테이프 같이 특정의 한 프로세스가 독점하여 사용하는 자원

         4) 공용 자원

            - 주기억장치, CPU같이 다수의 프로세스들 사이에서 공동으로 사용되는 자원

         5) 재사용(reusable) 자원

            - 전체 총량이 고정되고 부수적인 자원들이 생성되거나 파괴되지 않는 경우

         6) 소비(consumable) 자원

            - 전체 용량이 고정되지 않고 부수적인 자원들이 생성되거나 파괴되는 경우

     (6) 시스템 모델

         - 프로세스의 자원 사용 순서

         1) 자원요구(resource request)

            - 한 프로세스가 자원을 요구할 때 다른 프로세스가 이미 그 자원을 사용중이면 할당받을 수 

              없으므로 자원을 요구한 프로세스는 그 자원을 사용할 수 있을 때까지 기다린다

         2) 자원할당(resource allocation)

            - 프로세스는 운영체제로부터 자원을 할당받아 그 자원을 사용하여 수행을 계속한다

         3) 자원해제(resource release)

            - 프로세스는 이전의 자원요구에 의해 할당받았던 자원을 사용 후에는 운영체제에게 반납한다


2.3.2 교착상태 발생의 4가지 필요조건

     (1) 상호배제(mutual exclusion) 조건

         - 프로세스가 사용중이면 다른 프로세스는 반드시 기다려야 한다. 프린터

         - 프로세스들이 자원을 배타적으로 점유하고 있어서 다른 프로세스들이 그 자원을 사용할 수 

           없도록 만든다.

     (2) 점유와 대기(block and wait) 조건 : 부분할당

         - 프로세스들은 동일한 자원이나 다른 종류의 자원을 부가적으로 요구하면서 이미 어떤 자원을

           점유하고 있다

         - 대기조건

            : 프로세스가 자원을 요청할 때 그 프로세스는 어떠한 자원도 할당받지 않은 상태여야 한다.

     (3) 비선점(non-preemption) 조건

         - 자원은 사용이 끝날 때까지 이들을 갖고 있는 프로세스로부터 제거될 수 없다.

         - 자원들은 그들을 점유하고 있는 프로세스로부터 벗어나지 못하고 단지 프로세스들 자신이 

           점유한 자원을 해제할 수 있다

     (4) 환형대기(circular wait) 조건

         - 프로세스와 자원들이 원형을 이루며 각 프로세스는 자신에게 할당된 자원을 가지면서 상대방의

           자원을 상호 요청하는 경우


2.3.3 교착상태의 연구분야

     (1) 교착상태의 예방(deadlock prevention)

         - 교착상태의 발생 가능성을 사전에 모두 제거하도록 시스템을 조절

         - 가장 명료한 해결책으로 널리 사용됨

         - 자원의 비효율적인 이용결과를 낳을 수 있음

         - 교착상태 발생 필요조건의 네 가지 중 하나를 부정함으로써 수행 됨

     (2) 교착상태의 회피(deadlock avoidance) 기출94

         - 교착상태 발생 가능성을 인정하고 교착상태가 발생하려고 할 때 이를 적절히 피해가는 방법

         - 예방보다는 좀더 덜 엄격한 조건을 요구

     (3) 교착상태의 발견(deadlock detection) 기출95

         - 불안정 상태가 만들어졌을 때 검출 알고리즘 실행

         - 원하는 것이든지 아니든지 교착상태가 발생하도록 허용하여 교착상태가 일어났는지를 판단하고

           교착상태에 관련된 프로세스와 자원을 조사하여 결정해 내는 방법

         - 프로세스와 자원을 결정해 내면 교착상태를 시스템으로부터 제거할 수 있다

     (4) 교착상태의 회복(recovery from deadlock)

         - 시스템으로부터 교착상태를 제거하여 이후로는 시스템이 교착상태에 빠지지 않고 잘 진행되게 함

         - 교착상태에 빠진 프로세스가 완료되고 그 프로세스에 할당된 자원을 회수할 수 있도록 한다

         - 교착상태 발생 확률이 작거나 회복비용이 적게 소요되는 컴퓨터 시스템에서 사용할 때 유리


2.3.4 교착상태의 해결방안

     (1) 교착상태의 예방

         - 사전에 교착상태의 발생 가능성을 없애는 것(교착상태 발생요건중 1개만 부정)

         - 자원의 낭비가 따른다

         1) 점유와 대기조건의 부정

            - 프로세스는 필요한 모든 자원을 한꺼번에 요청하고, 시스템은 요청된 자원들을 전부 할당하든

              지 전혀 할당하지 않든지 하는 방식

            - 장점 : 프로세스들이 자원을 기다리는 동안은 아무 자원도 점유하지 않으므로 점유와 대기조건

                     이 부정되며 교착상태도 발생하지 않는다

            - 단점 : 자원 낭비와 비용 증가, 자원공유 불가능, 무한 연기 발생 가능

         2) 비선점 조건의 부정

            - 어떤 자원을 가지고 있는 프로세스가 더 이상 자원 할당 요구가 없으면 가지고 있던 자원을

              반납하고, 필요시 다시 자원을 요구하는 방법

            - 문제점 : 비용증가, 무한연기 발생가능(시간낭비)

         3) 환형대기 조건의 부정

            - 모든 프로세스에게 각 자원의 유형별로 할당순서(고유번호)를 부여하는 방법

            - 문제점 : 새로운 자원 추가 시 재구성 해야함

         4) 상호배제 조건 부정

            - 공유할 수 없는 자원을 사용할 때 성립

     (2) 교착상태의 회피

         - 시스템의 운영중 상황을 보아가면서 교착 상태 가능성을 피해 가는 것

         1) 안전 상태와 불안전 상태

            - 안전상태 : 시스템이 특정 순서대로 각 프로세스에게 자원을 할당할 수 있고 교착상태를 

                         방지하여 모든 작업이 완료될 수 있는 상태

            - 불안전 상태 : 교착상태가 발생할 수 있는 상태

         2) 은행가(banker) 알고리즘

            - 알고리즘 구현을 위한 기본 자료구조

              * n : 시스템의 프로세스 수  m : 자원 형태(종류)의 수

              ① Available : 각 자원의 형태별로 사용가능한 자원의 수를 표시하는 길이가 m인 벡터

                            Available[j] = k라면, 자원형태 Rj인 자원이 k개가 남아 있다

                            (사용 가능하다)는 의미(잔여량)

              ② Max : 각 프로세스의 최대 자원의 요구를 정의하는 n×m 행렬 Max[i,j] = k라면

                        프로세스 Pi는 자원 형태가 Rj인 자원을 최대로 k개까지 요구할 수 있다는

                        의미(최대 요구량)

              ③ Allocation : 현재 각 프로세스에 할당된 자원의 수를 정의한 n×m 행렬 

                             Allocation[i,j] = k라면 프로세스 Pi는 현재 Rj라는 자원형태를 k개 할당 

                             받고 있다는 의미(할당량)

              ④ Need : 각 프로세스의 남아있는 자원요구를 표시하는 n×m 행렬 Need[i,j] = k라면 

                        프로세스 Pi는 자신의 작업을 종료하기 위해 자원형태 Rj를 추가로 k개 더 요

                        구한다는 의미(추가 요구량)

            <은행가 알고리즘>

              : Requesti를 프로세스 Pi를 위한 요청 벡터라 함. Requesti[j] = k라면 프로세스 Pi는

                Rj형 자원을 k개 요구한다. 프로세스 Pi가 자원을 요청하면 다음의 조치를 취함

              (ㄱ) Requesti ≤ Needi라면 (ㄴ)으로 가고 그렇지 않으면 최대 요구량을 초과하기

                   때문에 오류(요구량 > 필요량 → error)

              (ㄴ) Requesti ≤ Available라면 (ㄷ)으로 가고 그렇지 않으면 자원이 부족하기 때문에

                   대기(요구량 > 잔여량 → 대기)

              (ㄷ) 시스템은 상태를 다음과 같이 수행하여 요구된 자원들을 프로세스에게 할당되도록 

                   한다

                  Available(잔여량) = Available(잔여량) - Requesti(요구량)

                  Allocationi(할당량) = Allocationi(할당량) + Requesti(요구량)

                  Needi(필요량) = Needi(필요량) - Requesti(요구량)

         2) 안전 알고리즘

            <안전 알고리즘>

              (ㄱ) Work, Finish를 각각 길이가 m, n인 벡터라고 하면, Work = Available로

                   Finish[i] = false, i = 1, 2, 3, ..... , n으로 초기화 한다. Work에는 남아 있는

                   자원 수인 Available의 임시변수이다.

              (ㄴ) 다음과 같이 되는 i 값을 찾는다.

                   a) Finish[i] = false

                   b) Needi ≤ Work

                   이런 i 값이 존재하면 (ㄷ)으로 없으면 (ㄹ)로 간다.

              (ㄷ) 자원을 할당한 후 해제한다.

                   Work = Work + Allocationi 

                   Finish[i] = true

                   (ㄴ)단계로 간다.

              (ㄹ) 만약 모든 i에 대하여 Finish[i] = true면 시스템은 안전 상태

     (3) 교착상태의 발견

         - 시스템 운영중에 교착상태가 발생했는지 결정하고 교착상태에 관련된 프로세스와 자원을 발견

         1) 자원 유형마다 여러 개의 자원이 있는 경우

            - 자료구조 정의

              ① Available : 각 자원의 형태별로 사용가능한 자원의 수를 표시하는 길이가 m인 벡터

              ② Allocation : 현재 각 프로세스에 할당된 자원의 수를 정의한 n×m 행렬

              ③ Request : 각 프로세스의 현재 요구를 표시하는 n×m 행렬

              ④ Request[i,j] = k라면 프로세스 Pi는 자원형태 Rj의 자원을 k개 더 요구


            <발견 알고리즘>

              (ㄱ) Work, Finish를 각각 길이가 m, n인 벡터라고 하면, Work = Available로 초기화

                   한다. i = 1, 2, 3, ..... , n일 때 만약 Allocation ≠ 0이면 Finish[i] = false 이고,

                   그렇지 않으면 Finish[i] = true로 초기화한다.

              (ㄴ) 다음과 같이 되는 인덱스 i 값을 찾는다.

                   a) Finish[i] = false

                   b) Requesti ≤ Work

                   이런 i 값이 존재하면 (ㄷ)으로 없으면 (ㄹ)로 간다.

              (ㄷ) Work = Work + Allocationi 

                   Finish[i] = true

                   (ㄴ)단계로 간다.

              (ㄹ) Finish[i] = false면 1 ≤ i ≤ n인 범위에서 시스템은 교착상태

         2) 자원 유형마다 하나의 자원이 있는 경우 교착 상태 발견

            - 대기 그래프 사용 : 자원할당 그래프에서 자원형태 노드들을 삭제하고 적절히 연결선들을

                                 제거하여 사용

            - 대기 그래프가 사이클을 포함하는 경우 교착 상태 존재

     (4) 교착상태의 회복

         - 시스템이 교착상태에 빠지면 교착상태는 하나 또는 그 이상의 교착상태 필요조건을 제거함으로서 

           회복된다

         1) 프로세스 중지

            ① 교착상태 프로세스를 모두 중지하는 방법

               : 교착상태 사이클 제거시 효과적, 비용이 많이 든다

            ② 교착상태 사이클이 제거될 때까지 한 프로세스씩 중지 : 오버헤드가 걸림

            ③ 한 프로세스씩 중지를 위한 희생자 선택의 원칙(희생자 선택 시 고려사항) 기출96

               - 프로세스의 우선순위

               - 수행된 시간과 종료 시간(얼마나 수행되었고 앞으로 얼마나 수행될 것인가)

               - 사용한 자원의 유형과 수(얼마나 많은 자원을 사용중인가)

               - 종료를 위해 필요한 자원의 수(얼마나 많은 자원을 더 필요로 할 것인가)

               - 복귀하는데 포함된 프로세스의 수(몇 개의 프로세스를 복귀시킬 것인가)

               - 대화식인지 일괄 처리식인지의 여부

         2) 자원 선점

            - 교착상태의 프로세스로부터 자원을 선점하여 다른 프로세스에게 제공

            - 자원 선점 시 고려해야할 문제(교착상태 처리 시 강제해제의 문제점)

               : 희생자 선정문제, 복귀문제, 기아상태 문제


2.4 CPU 스케쥴링

2.4.1 스케쥴링

     (1) 개요

         1) 정의 - 작업을 처리하기 위해 프로세스들에게 중앙처리 장치나 각종 처리기들을 할당하기 위한

                   정책을 계획하는 것

         2) 목적

            - 공정한 스케줄링 : 무한대기에 빠지는 프로세스가 없어야 함

            - 처리능력 극대화 : 단위 시간당 처리량의 최대화

            - 응답시간 최소화 

            - 반환시간 예측가능 

            - 우선순위제 실시

            - 무한대기 상태 회피

            - 응답시간과 자원이용간의 균형유지

            - 균형있는 자원 사용

         2) 스케쥴링의 기준

            - I/O중심 프로세스와 연산중심 프로세스의 적절한 혼용

            - 작업형태 고려  - 우선순위 고려  - 페이지 부재율 고려  - 자원선점 고려

            - 버스트시간 고려  - 잔여 실행시간 고려

         3) 스케쥴링 알고리즘 성능의 기준

            - CPU이용율  - 처리율  - 수행시간  - 대기시간  - 응답시간

     (2) 프로세스 스케쥴링의 분류

         1) 단계별 분류

            ① 상위수준 스케쥴링(high level scheduling)

               - 시스템의 자원을 어느 작업에 할당할 것인가를 결정 = job 스케쥴링 = 승인 스케줄링

            ② 중간수준 스케쥴링(intermediate level scheduling)

               - CPU를 차지할 프로세스를 결정

               - 프로세스들을 일시중지시키거나 활성화시키는 작업을 수행하여 시스템의 부하를 조정

            ③ 하위단계 스케쥴링(low level scheduling)

               - 어느 프로세스에게 CPU를 할당할 것인가를 결정

               - 수행 속도가 빠르다

         2) 방법별 분류 기출96

            ① 선점(preemptive) 스케쥴링 - RR, SRT, 다단계(피드백) 큐

               - 한 프로세스가 CPU를 차지하고 있을 때 우선순위가 높은 다른 프로세스가 현재

                 프로세스를 중지시키고 자신이 CPU를 차지할 수 있는 경우

               - 높은 우선순위를 가진 프로세스들이 빠른 처리를 요구하는 시스템에서 유용

               - 빠른 응답시간을 요구하는 시분할 시스템에 유용

               - 높은 우선순위 프로세스들이 들어오는 경우 오버헤드를 초래

            ② 비선점(nonpreemptive) 스케쥴링

               - 한 프로세스가 CPU를 할당받으면 다른 프로세스는 CPU를 점유못함 

               - 짧은 작업을 수행하는 프로세스가 긴 작업이 종료될 때까지 기다려야 함

               - 모든 프로세스들에게 공정하고 응답시간의 예측이 가능

         3) CPU 스케쥴링 알고리즘별 분류

            ① 우선순위(priority) 스케줄링 - nonpreemptive

               - 프로세스에게 우선순위를 부여하여 우선순위가 높은 순서대로 처리

               - 일반 프로세스는 0~15사이, 실시간 프로세스는 16~31 사이의 우선순위를 받는다.

               ㄱ) 정적(static) 우선순위 방법

                   - 주변 환경 변화에 적응하지 못하여 실행중 우선순위를 바꾸지 않음, 

                     구현이 쉽고 오버헤드가 적다

               ㄴ) 동적(dynamic) 우선순위 방법

                   - 상황 변화에 적응하여 우선순위를 변경, 구현이 복잡, 오버헤드 많다,

                     시스템의 응답속도를 증가시켜 효율적

            ② 기한부(deadline) 스케줄링 - nonpreemptive

               - 작업을 명시된 시간이나 기한내에 완료되도록 계획

               - 작업시간이나 상황등 정보를 미리 예측하기가 어렵다

            ③ FIFO 스케줄링 - nonpreemptive

               - 프로세스들은 대기 큐에 도착한 순서대로 CPU를 할당 받는다

               - 일괄처리 시스템에서 주로 사용, 작업 완료 시간을 예측하기 용이

               - 짧은 작업이 긴 작업을 기다리게 됨

               - 중요하지 않은 작업이 중요한 작업을 기다리게하여 불합리

            ④ 라운드로빈(round robin) 스케줄링 - preemptive 기출94 기출96

               - FCFS에 의해서 프로세스들이 보내지며

               - 각 프로세스는 같은 크기의 CPU 시간을 할당받음, CPU의 타임슬라이스에 의해 제한 받음

               - 시분할 방식에 효과적, 할당시간의 크기가 매우 중요

               - 할당시간이 크면 FCFS와 같게되고, 작으면 문맥교환이 자주 일어난다.

               * SRR(selfish round robin)

                  - 프로세스가 시스템에 들어오면 우선순위가 활성 큐 내의 프로세스의 수준에 도달할

                    때까지 보류 큐에 머물러 있는 스케줄링 기법

            ⑤ SJF(shortest job first) 스케줄링 - nonpreemptive 기출94

               - 준비 큐 내의 작업 중 수행시간이 가장 짧다고 판단되는 것을 먼저 수행

               - FCFS보다 평균 대기 시간을 감소, 큰 작업은 시간 예측이 어렵다

               - 짧은 작업에 유리

            ⑥ SRT(short remaining time) 스케줄링 - preemptive

               - 가장 짧은 시간이 소요된다고 판단되는 프로세스를 먼저 수행

               - 남은 처리 시간이 더 짧다고 판단되는 프로세스가 준비 큐에 생기면 언제라도 실행중인 

                 프로세스가 선점 됨, 시분할 시스템에 유용, 서비스를 받은 시간 기록

               - 긴 작업은 SJF보다 대기 시간이 길다, 이론적으로 대기시간 최소

            ⑦ HRN(highest response ratio next) 스케줄링 - nonpreemptive

               - 긴 작업과 짧은 작업간의 지나친 불평등을 어느 정도 보완한 기법

               - 짧은 작업이나 대기시간이 긴 작업은 우선순위가 높아진다

               - 우선순위 = 

            ⑧ 다단계 큐(multilevel queue) 스케줄링 - preemptive

               - 작업들을 여러 종류의 그룹으로 나누어 여러개의 큐를 이용하는 기법

            ⑨ 다단계 피드백 큐(multilevel feedback queue) 스케줄링 - preemptive 기출95 기출96

               - 입출력 위주와 CPU 위주인 프로세스의 특성에 따라 서로 다른 CPU의 타임 슬라이스 부여

               - 짧은 작업에 유리, 입출력 위주의 작업에 우선권을 줌

               - 하위단계 큐일수록 할당시간은 커진다

            ⑩ FSS(fair share scheduling)

               - 프로세스들 집합간에 프로세스의 스케줄링을 지원

               - UNIX 환경에서 서로 관계 있는 사용자들에게 한정된 비용으로 시스템 자원을

                 사용할 수 있게 해준다.


제3장 기억장치 관리

3.1 주기억 장치 관리

3.1.1 개요

     (1) 용어

        - 주기억 장치 : CPU가 명령이나 자료를 직접 인출 혹은 반환할 수 있는 기억장치의 부분

        - 가상기억장치 : 특정 컴퓨터 시스템에서 주기억 장치의 이용 가능한 기억 공간보다 훨씬 큰 주소

                         지정을 할 수 있도록 하는 기법

        - 단일 사용자 시스템 : 한 사람이 CPU와 모든 주기억 장치를 할당받아 사용하는기법

        - 동적적재 : 기억장치의 효율을 높이기 위해 사용. 사용되지 않는 루틴은 주기억장치에 적재되지 

                     않는다

        - 동적연결 : 언어 서브루틴 라이브러리들과 같은 시스템 라이브러리의 연결이 수행시간까지 지연

        - 절대로더 : 기계어로 된 프로그램을 미리 지정된 주기억 장치에 적재

        - 재배치로더 : 적재시간에 주기억 장치의 사용여부에 따라 주기억 장치의 여러 다양한 곳에 적재

        - 링킹로더 : 프로그램 적재시 필요한 프로그램들을 결합하여 이진 프로그램 이미지를 주기억장치에 

                     적재

        - 링키지에디터 : 링킹로더의 기능과 더불어 이진프로그램 이미지를 디스크에 보관

     (2) 기억장치 관리 정책

        1) 반입정책(fetch strategic) - 프로그램이나 데이터의 주기억장치 적재 시기 결정

           ① 요구 반입정책(demand fetch strategic)

               : 프로그램이나 자료에 대한 요구가 있을 때 주기억 장치로 가져오는 방식

           ② 예상 반입정책(anticipatory fetch strategic) : 요구가 없어도 앞으로 필요한 것이라 예상되는 

                                                        내용을 주기억장치로 미리 가져오는 방식

        2) 배치정책(placement strategic) - 프로그램이나 자료를 주기억장치의 어디에 위치시킬 것인 가를 

                                          결정하는 정책

           ① 최초적합(first-fit) : 주기억장치 공간 중 프로그램을 저장할 수 있는 최초의 유용한 공간에 

                                 우선적으로 할당하는 방법 기출94

              - 장점 : 기억장치 전체를 조사하지 않아 배치결정을 빨리 내릴 수 있다

              - 단점 : 사용되지 않은 작은 크기의 가용공간이 누적될 경우 할당결정이 늦을 수 있다

             * NEXT-fit

                - 최초 적합의 변형으로 이전에 탐색이 끝난 그 다음부터 사용가능한 공백을 탐색

           ② 최적적합(best-fit) : 주기억장치의 가용공간 중 프로그램을 저장할 때 가장 작은 공간이 남는 

                                 분할에 할당

              - 장점 : 가용공간을 반만 탐색해도 필요 공간을 찾음

              - 단점 : 가용공간이 크기 순으로 정렬되어 있지 않으면 모든 가용공간을 검색해야 한다

                     : 기억장소 정렬에 많은 시간 요구

                     : 할당한 후 작은 가용공간이 또 만들어짐

           ③ 최악적합(worst-fit) : 주기억 장치 가용 공간중 가장 큰 공간에 프로그램을 할당

              - 장점 : 할당후 남은 공간은 크므로 다른 프로그램 실행가능

              - 단점 : 가용공간이 크기순으로 되어있지 않으면 모든 공간을 검색해야 함

                     : 큰 프로그램이 적재될 가용공간이 없어진다

        3) 교체정책 - 새로 입력되는 프로그램이나 자료에 필요한 기억장소 확보를 위해 어떤 프로그램을 

                      제거할 것인가를 결정하는 정책

     (3) 기억장소 할당

        1) 연속 기억장치 할당 - 각 프로그램이 주기억장치 내에 인접되어 연속된 하나의 블록을 차지하도록  

                                배치

        2) 불연속 기억장치 할당 - 하나의 프로그램이 여러 개의 블록으로 나뉘어 분산 배치되는 방법


3.1.2 주기억장치 관리 기법

     (1) 단일 사용자 연속 기억 장치 할당

            ① 기억장치 할당 방법

               : 주기억장치 용량을 초과하는 프로그램은 실행할 수 없으며 한 순간에 오직 한 명의

                 사용자만이 주기억장치를 전용하여 사용하므로 다른 사용자는 기다림

            ② 장점 : 단순하며 이해하기 쉽다

            ③ 단점 : 기억장치의 빈 공간을 이용하지 못하기 때문에 기억장치의 낭비

                    : 한 사용자만이 기억장치로 전용하므로 자원낭비가 심하다

                    : 입출력 시 CPU는 유휴상태

                    : 사용하지 않는 프로그램이 기억장치 내에 위치

        1) 상주 모니터 - 어떤 작업이 다음에 수행되어야할 것인지에 대한 정보유지

        2) 오버레이 기법

           - 디스크에 프로그램을 유지하고 운영체제에 의해서 기억장치를 교체시키는 방법

           - 프로그램 수행도중 주기억장치의 프로그램 일부가 더 이상 필요하지 않다면 그곳에 보조기억 

             장치로부터 다른 프로그램을 적재(load)하여 겹쳐서 사용하는 방법

           - 한정된 기억장치를 확장하여 사용할 수 있는 개념 제공

           - 기억장치 할당방법 : 프로그램이 기억장치의 크기보다 클 경우에는 프로그램 수행을 허용

                              : 오버레이 중첩을 이용하여 오버레이 영역보다 커다란 프로그램도 처리 가능

        3) 교체기법(swapping)

           - 다중 프로그래밍 환경에서는 CPU 할당 시간이 초과되면 기억장치 관리자는 실행이 끝난

             프로세스를 보조기억 장치로 보내고 다른 프로세스를 주기억장치의 가용 공간으로 불러와 실행

           - 교체 순서 : 한번에 하나의 사용자 프로세스만 주기억장치를 할당받는다

             ① 사용자 프로세스가 주기억장치에서 수행되다 교체된다

                - 프로세스의 실행도중 입출력 발생 시

                - CPU 사용 할당시간이 초과될 때 

                - 프로세스 수행이 완료될 때 

             ② 교체영역이 보조기억 장치에 복사됨(swap out)

             ③ 다음 사용자 프로세스가 주기억 장치에 들어와 실행됨(swap in)

        4) 시스템의 보호

           - 사용자 프로그램으로부터 운영체제를 보호하기 위해 CPU 내부에 경계 레지스터를 둔다

           - 경계 레지스터는 운영체제의 제일 마지막 명령의 주소 저장

     (2) 고정 분할 기억장치 할당(MFT : Multiple Contiguous Fixed parTition allocation) 기출95

        - 주기억 장치를 일정수의 고정된 크기들로 분할하여 실행중인 여러 프로세스에게 할당하는 기법

           (=고정분할 다중 프로그래밍)

        - 입출력 요구가 생기게 되면 데이터의 입출력 처리가 끝나기 전까지는 작업을 중단해야 한다.

        - CPU 계산과 입출력은 동시에 행해질 수 있다.

        - 입출력 속도는 CPU 속도에 비해 엄청 느리다.

         1) 절대번역과 적재(absolute compile & loading)

            - 한 작업이 실행준비가 되어있다 하더라도 지정된 자신의 분할이 이미 차 있으면 다른 분할이 

              이용가능 하더라도 그 작업은 기다려야 한다

            - 미리 정해진 주기억 장치의 적재 위치에서만 해당 프로그램을 실행할 수 있게 하는 것 

            - 장점 : 간단하고 구현하기 쉽다

            - 단점 : 기억장치의 낭비 발생

         2) 재배치 번역과 적재(relocation compile & loading)

            - 모든 작업을 하나의 작업 큐에 넣어서 어느 분할에서든지 실행 가능하도록 한 기법

            - 장점 : 기억장소의 낭비가 없다

            - 단점 : 재배치 번역과 적재의 설계가 복잡(운영체제가 복잡)

         3) 고정분할 기억장치 할당에서의 보호

            - 여러 개의 경계 레지스터(합당한 사용자 주소범위를 나타내는 하한 레지스터와 상한 레지스터

              로 되어 있다)를 사용

         4) 고정분할 기억장치 할당의 장단점

            - 장점 : 다중 프로그래밍 가능, 수행속도 증가로 CPU를 효율적으로 사용

                   : 한 작업이 입출력을 수행할 때 CPU는 다른 작업의 계산을 처리할 수 있다.

            - 단점 : 단편화에 의해 기억장치의 낭비가 크다

                   : 수행할 프로그램의 크기를 미리 알고 있어야 함

     (3) 가변분할 기억장치할당(MVT : Multiple contiguous Variable parTition allocation) 기출95

         - 고정된 분할의 경계를 없애고 각 작업의 필요한 만큼의 기억장치를 할당

         - 가장 합리적인 분할의 크기를 결정하여 각 작업에게 주기억장치로 할당, 바운드 레지스터 필요

         - 장점 : 단편화방지, 자원의 효율적 사용

         - 단점 : 기억장치 집약시간 낭비

                : 작업의 크기가 기억장치 용량에 의해 제약됨, 외부단편화 심각

     (4) 기억장치의 단편화(Memory Fragmentation) 기출96

         - 단편화 : 작업을 수행하기 위한 기억장소 분할영역이 부족하거나 남는 경우

         - 단편화 종류 : 내부 단편화 - 하나의 분할에 작업을 할당하고 남은 빈 공간 

                       : 외부 단편화 - 대기중인 작업이 분할영역보다 커서 분할 전체가 빈 공간으로 있을

                                       때의 상태

         1) 고정분할 기억장치 할당에서의 단편화

            : 사용자 작업의 크기가 정확하게 분할에 맞지 않거나 작업보다 분할이 너무 작아서 이 분할에 

              대기중인 어떤 작업도 적재될 수 없는 경우 발생

         2) 가변분할 기억장치 할당에서의 단편화

            : 할당초기와 초기작업이 끝나 그들이 사용하던 기억공간이 공백으로 남을 때까지 기억공간의 

              낭비가 거의 없거나 분명하게 나타나지 않는다. 그러나, 실행을 기다리는 작업들에게 이 공백을

              할당하면서부터 기억장치의 단편화가 발생

         - 단편화의 해결 방법

            ① 공백의 통합(coalescing holes) : 가용 공간 중 이웃되는 가용공간을 하나의 커다란

                                             가용공간으로 만드는 것

            ② 기억장소 집약(storage compaction)

               : 가변분할 다중 프로그래밍에서 존재하는 여러 개의 작은 공간을 모아 하나의 커다란

                 기억공간을 만드는 것 = garbage collection

               : 장점 : 모든 미사용 공간을 모으므로 통합보다 메모리를 효율적으로 사용

                 단점 : 집약이 실행되는 동안 모든 일을 중지

                      : 실시간 처리 시스템의 경우 작업에 치명적

                      : 기억장치의 작업들이 모두 재배치되어야 함 

                      : 시스템 효율저하, 생산적으로 사용 가능한 시스템 자원을 소비한다.


3.2 가상 기억장치의 구성

3.2.1 가상 기억장치의 개요

     - 가상 기억장치(virtual memory)

        : 주기억장치에서 이용 가능한 공간보다 더 큰 저장 공간을 보조기억 장치에 생성하여 마치

          주기억장치의 연속된 공간처럼 사용하는 기억장치

        : 사용자의 논리적 기억장치를 실기억 장치로부터 분리시킨 것으로 요구페이징으로 구현

        : 실행중인 프로세스에 의해 참조되는 주소를 기억장치에서 사용할 수 있는 주소와 분리

        : 여러 사용자가 같이 사용

     - 세그먼트(segment) : 블록의 크기가 다를 때 

     - 페이지(page) : 블록의 크기가 같을 때

     - 가상주소(V) : 프로그래머에 의해 쓰여진 보조기억장치 번지

     - 실 주소(R) : 주기억장치의 사용 가능한 주소

     - 주소 사상(address mapping) : 보조기억장치에 존재하는 가상 번지를 주기억 장소의 실제 주소로 변환

     (1) 동적 주소 변환(DAT : dynamic address translation)

         : 프로세스가 수행될 때 가상주소를 실제 주소로 변환하는 기법

     (2) 블록 사상(block mapping)

         : 모든 내용을 한번에 사상할 수 없으므로 가상기억장치의 내용을 블록 단위로 분류하여 가상

           기억장소 블록이 실기억 장치의 어느 곳에 위치하는지 알아내 블록 단위로 사상하는 방법

         : 블록이 크면 - 사상기법 자체가 필요로 하는 기억공간을 줄일 수 있다

                       - 블록 이동시 전송시간이 많이 걸림

                       - 주기억장치가 많이 소요, 실기억 장소는 작아진다.

         : 블록사상을 통한 가상주소 변환


3.2.2 페이징(paging) 기법 기출94 기출95

     - 페이지는 블록단위로 보조기억장치로부터 주기억장치로 옮겨짐

     - 입력되는 페이지는 사용 가능한 페이지 프레임의 어느 곳에나 위치할 수 있다.

     - paging : 가상 메모리를 일정 크기의 블록으로 나눈 페이지를 주기억장치에 사상

              : 고정된 블록 크기로서 페이지와 관련된 가상기억장치 구성

     - 페이지 프레임 : 가상기억장치의 블록과 사상되는 주기억장치의 한 블록

                     : 고정된 페이지 크기의 정수 배에 해당하는 실기억 장치 주소에서 시작

     - 내부 단편화 발생, 페이지 크기의 1/2, 외부 단편화는 없다

     - V = (p, d) : p 페이지 번호, d 변위

     - 주소변환 방법

        1) 직접 사상에 의한 주소 변환 

           - 페이지 사상 테이블의 시작주소(b) + 페이지번호(p) = p'

           - p' + 변위(d) = 실제주소(r)

           - 컴퓨터 시스템의 속도를 절반으로 떨어뜨린다.(이를 보완하기 위해 캐시기억장치 사용)

           - 가상주소와 PMT(page map table)는 시스템 내의 제어프로세서 내에 존재하여 빠르게 실행

        2) 연관 사상 방법에 의한 주소 변환

           - 위치 지정이 아닌 내용지정의 연관 기억장치에 사상 페이지 사상표를 유지

           - 구현하는 비용이 많이 든다(캐시보다 비싸다), 가장 빠르고 융통성이 있음

           - 직접사상보다 구현이 어려움(잘 사용되지 않는다)

           - 실행 프로그램이 가상주소를 참조, 동적 주소변환을 빠르게 할 수 있다.

           - 연관 사상 테이블 내 페이지 p에 해당하는 페이지 프레임(p') + 변위(d) = r

        3) 연관 / 직접 사상에 의한 페이징 기법

           - 가장 최근에 참조된 페이지 항목들만 유지, 일부 사상 테이블만 포함

           - 캐시와 연관 기억장치의 이점을 효과적으로 혼합

           - 연관 사상 테이블을 먼저 찾은 다음 없으면 직접 사상 테이블을 찾는다.

           - 페이지 p가 사상 테이블에 있는 경우

              : 연관 사상 테이블 내 페이지 p에 사상되는 페이지 프레임(p') + 변위(d) = r

           - 페이지 p가 사상 테이블에 없는 경우

              : 페이지 사상 테이블의 시작주소(b) + 페이지번호(p) + 변위(d) = r

           - 연관 사상표(table) : 최근에 가장 많이 참조된 페이지

              페이지 사상표 : 연관 사상표에서 제외된 나머지 모든 페이지


3.2.3 세그멘테이션(srgmentation) 기법

     - segmentation : 가상 메모리를 가변 크기의 블록으로 나누어 주기억장치에 사상

                    : 가변 블록 크기로서 세그먼트와 관련된 가상 기억장치 구성

     - 외부 단편화 발생

     - 논리적 개념, 고정되어 있지 않다, 배열에 사상하는 세그먼트는 배열의 크기와 같다

     - 자료구조가 커지거나 작아짐에 따라 크고 작게 될 수 있다.

     - 프로세스는 현재 세그먼트가 주기억장치에 있을 때만 실행

     - 보호키를 사용하여 기억장치를 보호

     - V = (s, d) : s 세그먼트, d 변위

     - 접근제어(access control)

        : 엑세스 유형 ; read, write, execute, append

        : 세그먼트 엑세스 방법

          1) 엑세스 종류는 R, W, E, A의 4가지

          2) 4가지 엑세스의 조합으로 프로세스가 제한 없이 세그먼트를 엑세스 하는 것을 방지

          3) 16가지 조합 생성

          4) 세그먼트 보호의 기초 방법

     - 주소변환 방법

        1) 직접 사상에 의한 주소 변환

           - 세그먼트 사상 테이블의 시작주소(b) + 세그먼트번호(s) = s'

           - 세그먼트가 시작되는 실기억장치의 주소(s') + 변위(d) = 실제주소(r)


3.2.4 페이징 / 세그멘테이션 혼용 기법 기출96

     - 가상 기억장치의 구조에 중요한 이점을 제공, 크기는 페이지의 정수 배

     - 변환과정이 진행됨에 따라 실패할 수 있는 많은 단계가 존재

     - 참조된 페이지들은 부분적인 연관 기억장치에 있다.

     - 세그먼트 기법의 보완, 세그먼트를 페이지화 하는 것

     - V = (s, p, d) : s 세그먼트번호,  p 페이지번호,  d 변위

     - 내부 단편화 발생, 사상표가 차지하는 공간(table space)의 오버헤드도 증가

     - 주소변환 과정

        ① 연관 사상인 경우 : 연관 사상표를 탐색하여 발견되면 해당 페이지가 들어있는 주기억장치

                              내의 페이지 프레임 p'와 변위d를 더함

        ② 직접 사상인 경우 : 세그먼트 사상표의 시작주소(b) + 세그먼트번호(s) + 페이지 번호(p) + 

                              변위(d) = 실제주소(r)


3.2.5 요구페이징 기법 기출96

     - 보조기억 장치에 페이지들이 저장되어 있다가 실행 중인 프로세스에 의하여 그 페이지가 요구될 때만

        보조기억 장치에서 주기억장치로 옮겨지는 기법

     - 페이지 부재율을 낮게 유지해야 함 : 주기억장치 유효접근시간이 증가하여 수행시간이 늦어지게 된다.

     - 교체시간을 줄일 수 있다, 기억장치 사용량 절감, 많은 프로그램을 동시에 수행시킬 수 있다.

     - PMT필요, 비례할당, Thrashing문제 발생, 많은 테이블과 레지스터 필요, S/W가 복잡해진다.

   * 페이지 부재(page fault)

     - 프로세스에서 원하는 페이지가 주기억장치 내에 존재하지 않는 경우

     - 페이지 부재 처리시간의 구성요소 : 페이지부재 인터럽트 서비스, 페이지 교체, 프로세스 재실행


3.2.6 예상 페이징 기법

     - 예측 결정이 옳으면 프로세스의 실행시간은 대단히 감소

     - 정확한 결정이 내려질 수 있다. 

     - H/W 가격 하락 등 옳지 못한 결정의 결과도 그리 심각하지 않다.


3.3 가상 기억장치의 관리

3.3.1 가상 기억장치의 관리 기법

     1) 반입정책 - 보조기억장치에서 실기억장치로 사상한 페이지나 세그먼트의 적재시기 선택

     2) 배치정책 - 보조기억장치로부터 적재된 내용을 실기억장치의 어느 위치에 배치할 것인가

     3) 교체정책 - 실기억장치로 들어오는 페이지의 기억공간 확보를 위해 실기억장치의

                   어느 페이지를 가상 기억장치로 돌려보낼 것인가를 결정


3.3.2 페이지 교체 알고리즘

     (1) 최적교체 알고리즘

        - 다른 페이지 교체 기법들이 얼마나 최적성을 갖는지 비교하는데 사용

        - 현 페이지가 참조된 시점에서 그 이후로 가장 오랫동안 사용되지 않을 페이지를 교체

        - 장점 : FIFO의 모순을 피할 수 있는 알고리즘(최소의 페이지 부재율)

        - 단점 : 페이지 호출 순서에 대한 모든 상황을 미리 파악하고 있어야 하기 때문에 다루기가 어렵고 

                 비현실적

     (2) 무작위 페이지 교체 알고리즘

         - 교체할 페이지를 무작위로 선택

         - 장점 : 오버헤드가 적은 페이지 교체 기법

         - 단점 : 최악의 경우 바로뒤에 호출될 페이지도 교체될 수 있다

     (3) 선입선출(FIFO) 교체 알고리즘

         - 각 페이지가 참조된 때와 관계없이 주기억장치에 가장 먼저 들어온 페이지를 교체

         - FIFO 모순 : 페이지 프레임의 수가 증가될 때 페이지 부재가 더 증가하는 것

         - 장점 : 이해가 쉽고 설계가 간단

         - 단점 : 중요 페이지가 오랫동안 페이지 프레임을 차지 했다는 이유로 교체될 수 있다

     (4) 2차 기회 페이지 교체 알고리즘(SCR : second chance replacement)

         - 페이지의 참조비트가 0이면 교체하고 참조비트가 1이면 0으로 바꾼 다음 큐로 피드백 시켜

           두 번째 기회를 부여한 후 다음 페이지를 조사

     (5) LRU(least recently used) 교체 알고리즘 기출94

         - 한 프로세스에서 사용되는 각 페이지마다 카운터를 두어 현 시점에서 가장 오랫동안 사용되지

           않은 페이지를 제거

         - 단점 : 시간 오버헤드가 발생, 실제로 구현하기 복잡

     (6) LFU(least fraquence used) 알고리즘

         - 사용된 빈도(호출회수)가 가장적은 페이지를 교체, 구역성 문제 발생

         - 단점 : 바로 불러온 페이지가 교체될 수 있다

     (7) NUR(not used recently) 교체 알고리즘

         - 최근에 사용되지 않은 페이지를 교체. 2개의 bit를 둔다(참조 비트, 변형 비트)

         - 단점 : 현재 실행중인 페이지도 교체할 수 있다

     (8) Working Set - 프로세스가 최근 참조하는 페이지들의 집합에 속하지 않는 페이지를 모아 놓는

                        방법으로 집합에 속하지 않는 페이지를 교체

     (9) 페이지 부재 빈도 (PFF(page fault frequency))

        - 현재 페이지 부재와 바로전의 페이지 부재 사이의 시간을 관찰하여 그 시간이 지금까지의

          최소시간보다 크다면 그 사이에 호출되지 않았던 페이지들을 모두제거


3.3.3 Thrashing 기출94 기출95

     - 페이지 교체가 너무 자주 일어나는 현상

     - 프로세스 처리 시간보다 페이지 교체 시간이 더 많아지는 현상

     (1) 원인 - 실제로 사용하는 수만큼의 충분한 페이지 프레임을 갖지 못한 경우 페이지 부재가 빈번하게 

              발생하며 이 경우 실행중인 프로세스는 계속 페이지 교체를 수행해야 하므로 thrashing 현상이 

              발생

     (2) 방지 법 - 다중 프로그래밍의 정도를 낮추어야 한다(프로세스들에게 충분한 페이지 프레임을 

                  할당하여 주기억장치 내에 working set을 제대로 유지)

* 구역성(locality) = 국부성

 - 프로세스가 기억장치내의 정보를 균일하게 참조하는 것이 아니라 어느 순간 특정 부분을 집중적으로 참조

   ① 시간구역성(temporal locality) - 최근 참조된 기억장소가 가까운 장래에도 계속 참조될 가능성이 높다.

                                    (looping, subroutine, stack, counting, totaling)

   ② 공간구역성(spatial locality) - 임의 기억장소가 참조되면 그 근처의 기억장소가 연속적으로 참조될

                                  가능성이 높다(배열순례(array traversal), 순차적 코드의 수행,

                                                프로그래머가 관련 변수를 상호 이웃하게 선언하는 경향)

   - 기억장치에서 구역성이 중요한 이유 : 각 프로그램이 자주 참조하는 페이지들(working set)이

                                         주기억장치에 있으면 프로그램의 수행을 효율적으로 할 수 있다


3.3.4 Working Set 기출94

     - working set : 한 프로세스가 일정 시간동안 참조하는 페이지들의 집합

     - 프로그램이 효율적으로 수행되기 위해서는 working set이 주기억장치 내에 유지되어야 함


3.4 보조 기억장치

3.4.1 보조 기억장치의 개요

     * 보조 기억장치 ? 주기억장치에 저장되어 있는 정보를 제외한 모든 정보가 저장되어 있으며 필요에

                       따라 주기억장치에 전송

        1) 순차 기억 매체(SASD:Sequential Access Storage Device)

           - 자기 테이프 장치처럼 적절한 레코드가 찾아질때까지 차례차례 검색

        2) 직접 기억 매체(DASD:Direct Access Storage Device)

           - 자기 디스크 장치처럼 주소를 통해 직접 적절한 레코드를 찾아 가는 매체


3.4.2 자기 테이프(Magnetic Tape)

    (1) 개요

        1) 원리 - 자성 물질이 칠해진 테이프가 자기 테이프 구동장치의 헤드를 지날 때 전류를 변화시켜 

                  테이프에 정보를 기록

        2) 구성 - 총 9트랙 중 8개의 트랙은 데이터를 저장하는데 사용되고 나머지 1트랙은 데이터 전송 시

                  에러 여부를 검사하기 위한 패리티 비트를 저장하는데 사용

    (2) 특성 - 많은 양의 데이터 저장 가능

             - 속도가 느리고 순차접근을 하므로 데이터 보관용으로 사용

             - 순차처리만 가능(SASD:Sequential Access Storage Device)

             - 가격이 저렴하여 Backup용으로 많이 사용

             - 데이터를 읽기 위한 시간이 많이 걸린다

    (3) Label의 구성

        

        1) BOT(Beginning of Tape) : 테이프의 시작 부분

        2) VOL(Volume of Label) : 볼륨 레이블

        3) File Label : 파일의 앞과 뒤에 붙임

        4) TM(Tape Mark) : 레이블과 파일을 구분

        5) DATA : 실제 자료

        6) EOT(End of Tape) : 테이프의 끝 부분

    (4) 데이터의 구성

        

        󰠉<󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏󰠏>󰠋

                   물리 레코드 = BLOCK

        1) 논리 레코드(logical record) : 실제 저장되어 있는 레코드

        2) 물리 레코드(physical record) : 입출력 단위로 취급. 1개 이상의 논리 레코드로 구성 = block

        3) IRG(inter record gap) : 논리 레코드 사이의 간격

        4) IBG(inter block gap) : 블록간 데이터가 기록되지 않은 부분으로 테이프가 정상주행 속도에 

                                 이를 때까지의 시간과 멈출 때까지의 시간을 확보하기 위한 부분

        5) Blocking : 레코드의 입출력 효율을 높이기 위해 여러 개의 논리레코드를 하나의 블록으로

                      묶는 것

           * 블록화 하는 이유

              - 런 비용이 적게 든다, 물리적인 레코드의 기어용량을 절약, 입출력 실행 시 시간 절약

        6) 블록화 인수(blocking factor) : 한 물리 레코드 안에 있는 논리 레코드의 수


3.4.3 자기 디스크(Magnetic Disk)

    (1) 개요 기출94

        1) 구조 - 원형 금속판에 자성체를 입힌 것으로 트랙, 섹터, 실린더로 구성

           ① 트랙(track) - 디스크의 중앙을 중심으로 그려진 동심원

           ② 섹터(sector) - 트랙을 부채꼴 모양으로 분할한 것

           ③ 실린더(cylinder) - 각 면의 같은 위치에 있는 트랙들의 모임 또는 디스크 중앙으로부터 

                                같은 거리에 있는 트랙의 모임

        2) 접근시간

           ① 탐색시간(seek time) - 헤드를 적정 트랙으로 이동하는데 걸리는 시간

           ② 회전지연시간(rotational delay time) - 헤드가 트랙으로부터 데이터가 있는 섹터에

                                                  접근하는데 걸리는 시간

           ③ 헤드활성화시간(head activation time)

           ④ 전송시간(transmission time) - 데이터를 주고 받는데 걸리는 시간

    (2) 디스크 장치의 종류

        1) 이동 헤드 디스크 기출96

           - 판독/기록 헤드가 원하는 트랙에 위치하도록 액세스 암을 이동시켜 데이터를 읽거나 씀

           - 데이터 전송률 = 탐색시간 + 회전지연시간 + 헤드활성화시간 + 전송시간

           - 탐색 시간이 가장 많이 소요

        2) 고정 헤드 디스크

           - 각 트랙마다 읽기/쓰기 헤드를 가지고 있어 탐색시간을 없앰

           - 데이터 전송률 = 회전지연시간 + 헤드활성화시간 + 전송시간

    (3) 디스크 인터리빙(interleaving)

        - 디스크 제어기에게 기억장치로 데이터를 전송하기 위한 시간을 주기 위해 블록을 건너뛰도록 

          하는 기법

        - 지연시간 때문에 인접한 디스크 블록 사이에 두는 일정한 간격 : 인터리빙 인수

    (4) 그 외 디스크 장치

        1) 자기드럼 - 원통형 표면에 자성 데이터를 입힌 것

                    - 헤드가 움직이지 않으므로 탐색시간이 없다

                    - 저장 데이터량이 적고 부피에 비해 용량이 적다

                    - 자기디스크보다 접근시간이 빠르다

        2) 자기코어 - 환상형의 강자성체 물질로 되어 자화방향에따라 0,1을 표시

        3) 광 디스크 - 레이저 빔 이용. 처음 데이터 접근 시간은 느리나 연속된 데이터의 엑세스는 빠르다

                     - 접근시간은 자기 디스크보다 빠르다

    * 캐시(Cache)

       1) CPU 캐시 기억장치

          - CPU와 주기억장치의 속도차이를 완화시키기 위한 장치

          - 개념적으로 CPU와 주기억장치 사이에 존재하나 실제 CPU 내부에 있다

          - CPU는 캐시 기억장치와 주기억장치를 직접 접근할 수 있다

       2) 디스크 캐시

          - 국부적 휴리스틱 기법 사용 : 빈번히 사용되는 레코드가 무엇인지 알기 위해

          - 주기억장치와 디스크의 속도차이를 개선하기 위한 장치

          - 번번이 사용되는 기록을 주기억장치의 디스크 캐시 버퍼에 저장하여 사용

    (5) 디스크 가용공간 관리

        1) 비트 백터

        2) 연결 리스트 - 모든 가용 공간 블록들을 함께 연결

        3) 그룹핑(grouping) - 첫 번째 가용블록 내에 n개의 가용 블록들의 번지를 저장

        4) 카운팅(counting) - 첫 번째 가용블록의 주소와 그 첫 번째 블록에 연속된 가용 블록들의 개수를

                             보존


3.4.4 디스크 스케쥴링 기법

    (1) 개요

        1) 탐색시간 최적화 알고리즘(seek time optimization algorithm)

        2) 회전지연시간 최적화 알고리즘(rotational latency optimization algorithm)

        3) 스케쥴링 분류 기준

           ① 처리율(throughput) - 단위 시간에 디스크의 헤드가 찾을 수 있는 데이터의 수를 최대화

           ② 평균응답시간(mean response time)

           ③ 응답 시간의 편차(variance of response time)

              - 평균 응답시간을 줄이고 예측할 수 있도록 하는 것


    (2) 디스크 스케쥴링 기법

        1) FCFS(First Come First Served) 스케줄링

           - 가장먼저 입력된 요구가 우선적으로 서비스를 받는 방법

           ① 구현 - 대기 큐에 입력된 요구 순서대로 서비스 진행

           ② 특징 - 대기 큐의 순서대로 서비스하며 더 높은 우선 순위의 요청이 입력되어도 순서가

                     바뀌지 않아 공평성이 보장 됨

                   - 디스크 오버헤드(부하)가 커지면 응답시간이 길어진다

        2) SSTF(Shortest Seek Time First) 스케쥴링

           - 탐색 거리가 가장 짧은 요청을 먼저 처리하는 방법

           - 탐색 시간의 극소화, 극단적일 경우 기아상태 발생 가능

           ① 구현 - 현재 위치에서 가장 가까운 거리에 있는 요청을 서비스한다

                   - 대기 큐의 우선순위에 관계없이 다음 최단 거리 요청을 서비스

           ② 특징 - 실린더 지향 기법

                   - 가장 안쪽이나 바깥쪽의 트랙은 가운데 트랙보다 서비스를 받지 못하기 때문에 

                     응답시간의 편차가 크다

                   - FCFS보다 처리량이 많고 평균 응답시간이 짧다

                   - 일괄처리 시스템에 유용하고 응답시간의 편차가 크므로 대화형 시스템에 부적합

        3) SCAN 스케쥴링(엘리베이터 알고리즘)

           - Denning이 개발, SSTF가 갖는 응답시간의 편차와 차별을 극복하기 위한 방법

           - 오버헤드가 적은 경우

           ① 구현 - 헤드진행 방향과 같은 방향의 가장 짧은 거리에 있는 요청을 먼저 서비스하고 진행 중 

                     가장 바깥쪽까지 갔거나 더 이상 요구가 없으면 반대쪽으로 방향을 바꾸어 서비스

           ② 특징 - 디스크 오버헤드가 적어야 가장 좋은 효율을 가짐

                   - 대부분의 디스크 스케줄링의 기본 전략

                   - 밀도가 높은 쪽의 요청은 상당히 오랜 시간 대기하게 됨

        4) C-SCAN(Circular) 스케줄링 기출94 기출95

           - 가장 안쪽이나 가장 바깥쪽 실린더에 대한 차별을 제거

           ① 구현 - 바깥쪽 실린더에서 안쪽으로 진행하면서 최단거리의 요구를 서비스

                   - 더 이상 요구가 없으면 가장 바깥쪽에서 서비스하지 않은 요구로 이동하여 서비스

           ② 특징 - 진행도중 도착한 요청은 다음 수행 시 서비스

                   - 응답시간의 편차가 매우 적다

                   - 회전 시간의 최적화가 가능하며 부하(overhead)가 많이 걸리는 경우 효과적

        5) N-step SCAN 스케줄링

           - 서비스가 한쪽 방향으로 진행될 때 대기 중이던 요구들만 서비스

           ① 구현 - SCAN과 동일

                   - 진행 중 입력된 요청들은 한데 모아 반대방향 진행 때 서비스한다

           ② 특징 - 처리량과 평균응답시간에 있어 효율적

                   - SSTF 나 SCAN 방법보다 응답시간의 편차가 적다

                   - 한 실린더에 많은 요청이 도착해도 대기중인 요청만 처리하므로 무한대기가 없다

        6) 에센바흐 기법(Eshenbach scheme)

           ① 구현 - 헤드는 C-SCAN처럼 움직이는데 예외로 모든 실린더는 그 실린더에 요청이

                     있든 없든 전체 트랙이 한 바퀴 회전할 동안 서비스 받는다

           ② 특징 - 부하가 큰 항공예약 시스템을 위해 개발

                   - 탐색시간과 회전지연시간을 최적화

        7) SLTF(Shortest Latency Time First) 스케줄링

           - 회전지연시간의 최적화를 위한 기법

           ① 구현 - 디스크 헤드가 특정 실린더에 도착하면 여러 트랙을 가리키게 된다

                   - 이 여러 트랙에 대한 많은 요구들 중 가장 짧은 회전지연시간을 갖는 요청에

                     대해 먼저 서비스

           ② 특징 - 구현하기 쉽다. 이론적 최적값과 거의 일치

                   - 회전지연시간 최적화는 디스크 주변의 가장 가까운 섹터가 가장먼저 서비스되므로

                     섹터큐잉(sector queueing)이라 불림

                   - 고정헤드 디스크를 위한 스케쥴링 기법


3.4.5 실시간 처리 디스크 스케쥴링 알고리즘

     1) EDF(Earliest Deadline First) 스케쥴링

     2) P-SCAN(Priority SCAN) 스케쥴링

     3) FD-SCAN(Feasible Deadline SCAN) 스케쥴링

     4) SSEDO(Shortest Seek and Earlist Deadline by Ordering) 스케쥴링 

     5) SSEDV(Shortest Seek and Earlist Deadline by Value) 스케쥴링 

     6) SCAN-EDF 스케쥴링

     7) GSS 스케쥴링


제4장 정보관리

4.1 파일 시스템

4.1.1 개요

    (1) 파일의 개념

        - 프로그램과 데이터로 구성된 작성자에 의해 정의된 상호 관련 있는 정보의 집합체

        - 이름에 의해 참조되고 파일의 형태, 작성시기, 작성자, 길이 등의 속성을 갖는다

    (2) 파일의 종류

        1) 수행되는 기능에 따라 - 마스터, 트랜잭션, 보고서, 작업, 프로그램 파일

        2) 파일 구성에 따라 - 순차, 인덱스 된 순차, 인덱스, 직접, 다중 링 파일

    (3) 파일의 형태

        1) 원시파일   2) 목적파일   3) 텍스트파일

    (4) 디렉토리 개념

        - 디렉토리 구조는 파일 시스템에 있는 여러 파일을 구성하기 위한 기법을 제공

        - 디렉토리에 포함되는 정보 : 파일이름, 파일형태, 파일위치, 파일크기, 현재위치,

                                     보호, 사용 수, 시간, 날짜, 처리식별

    (5) 파일조작

        - 운영체제가 할일 : open, create, write, read, rewind, delete, insert, rename, close

        * 파일 단위 작업 - open, close, create, destroy, copy, rename, list

          레코드 단위 작업 - read, write, update, insert, delete

    (6) 파일 시스템의 기능

        1) 상위기능 - 디렉토리구조제공, 디스크공간할당 및 회수, 파일보호, 데이터 무결성

        2) 하위기능 - 오류검출, 디스크 스케줄링, 암호화, 블록전송

    (7) 파일 시스템의 요소

        1) 엑세스 방식 - 파일에 저장되어 있는 데이터에 대한 접근 방식

        2) 파일 관리 - 파일을 저장, 참조, 공유, 보호할 수 있는 기법 제공

        3) 보조기억장치 관리

        4) 무결성 유지 - 파일의 정보가 소실되지 않도록 보장

    (8) 파일의 특성 결정 기준

        1) 소멸성 - 파일에 자료를 추가하거나 제거하는 작업의 빈도 수

        2) 활성율 - 프로그램이 한 번 수행되는 동안 처리하는 레코드 수

        3) 크기 - 파일에 저장되어 있는 정보의 양


4.1.2 파일의 구조 및 접근방법

    (1) 파일의 구조

        1) 순차파일(sequential file) - 순차적으로 저장되며 일괄처리에 주로 사용

                                  - 테이프 장치와 천공카드, 프린터 등에 주로 쓰임

        2) 인덱스 된 순차파일(indexed sequential file)

           - 레코드가 각 레코드의 키에 따라 논리적 순서대로 배열되어 있는 것

           - 순차데이터 파일과 이 파일에 대한 포인터를 가지고 있는 인덱스로 구성

           - 정적 인덱스와 동적 인덱스방법을 사용하며 디스크 장치에 많이 사용

           - 파일 설계 시 고려해야 할 사항이 많다

        3) 직접파일(direct file)

           - DASD의 상세한 물리적 구조를 알아야 한다.

           - 다른 레코드를 참조하지 않고 어떤 임의의 레코드도 접근 가능

           - 대화형 처리에 이용되며 순차검색은 어렵다

    (2) 파일 접근 방법 기출95

        1) 순차접근(sequential access)

           ① 판독(read) - 테이프의 파일을 순차적으로 읽어 나가며 포인터는 자동 증가

           ② 기록(write) - 파일의 맨 뒤에 추가하며 파일 포인터는 추가된 내용의 끝으로 이동

        2) 직접접근(direct access)

           - 파일이 연속된 블록이나 레코드의 집합으로 간주, 키 값 필요, 가변길이 레코드에 부적합

           - 어떠한 블록도 직접 판독 또는 기록할 수 있다, 접근시간 빠르고 수정용이

        3) 색인순차접근(indexed sequential access method : ISAM)

           - 키 값에 따라 순차적으로 정렬되어있는 레코드에 대한 색인을 사용하여 접근

           - 색인 탐색 후 레코드 영역에서는 순차접근이 수행


4.1.3 기억장소 할당과 회수 방법

    (1) 연속할당(contiguous allocation)

        - 파일들이 디스크 내의 연속적으로 인접된 공간에 할당되는 것

        1) 장점 - 액세스 속도가 빠르고 파일 디렉토리가 단순하다

        2) 단점 - 새로 생성되는 파일의 기억공간의 크기를 미리 결정하며 단편화 발생

                - 원하는 만큼의 기억공간이 확보되지 않으면 그 파일은 생성되지 못함

                - 주기적 압축이 필요

    (2) 연결할당(linked allocation) - 파일이 저장되는 섹터들이 연결 리스트로 구성되고 각 섹터간에는

                                   연결을 위한 포인터를 가지고 있는 형태

        1) 장점 - 단편화가 일어나지 않으며 생성되는 파일의 크기가 문제되지 않는다

        2) 단점 - 논리적으로 연속된 블록의 검색에 긴 시간 요구

                - 연결리스트 구축에 추가시간이 요구되며 포인터를 위한 기억장소가 낭비

                - 포인터가 손상되면 데이터를 찾을 수 없다

    (3) 블록단위할당

        1) 블록체인 기법 - 연결할당과 비슷하나 할당단위가 블록 단위로 이루어지는 방법

           ① 장점 - 삽입과 삭제는 포인터만 수정하므로 간단

           ② 단점 - 속도가 느리다

        2) 색인 블록 체인 기법 - 파일마다 하나의 색인 블록을 두고 이 색인 블록에 포인터를 모아두어 

                                 직접접근을 가능하게 한 기법

           ① 장점 - 탐색 시간이 빠르다. 여러 개의 색인 블록을 서로 연결하여 사용 가능

           ② 단점 - 삽입 시 색인 블록을 재구성해야 함. 기억장치 낭비

        3) 블록지향 파일 사상 기법 - 포인터 대신 블록 번호를 사용


4.1.4 파일의 보호

    - 물리적인 손상으로부터 보호와 파일에 대한 무제한 접근을 방지하는 것

    (1) 보호방법 기출94

        1) 접근제어(access control) - 사용자에 따라 접근 대상을 다르게 구별

        2) 파일이름 명명(naming) - 파일의 이름을 알지 못하는 경우 접근대상에서 제외

        3) 암호(password) - 파일 접근 시 암호를 입력하여 접근하는 방법

    (2) 백업과 복구 - 주기적으로 시스템 파일을 복사하여 안전한 곳에 보관


4.2 보호와 보안

4.2.1 보호(Protection)

    (1) 보호 - 컴퓨터 시스템에 의하여 정의된 자원에 대하여 프로그램, 프로세스, 사용자의 접근을

               제어하는 기법

        1) 보호의 이유

           - 사용자가 자원에 대한 접근 제한을 의도적으로 위반하는 것을 방지

           - 시스템 내에서 동작중인 각 프로그램 요소가 시스템 자원의 정해진 사용정책대로 자원들을 

             사용하도록 보장

           - 시스템의 자원들이 무자격 사용자에 의하여 잘못 사용되는 것을 방지

        2) 보호영역

           - 한 프로세스는 하나의 보호영역에서만 동작하며 보호영역은 프로세스가 접근 가능한 자원을

              의미

           - 하나의 영역은 접근권한의 집합이고 접근권한은 어떤 프로세스가 객체에 대한 조작을 수행할

              수 있는 능력

    (2) 보호기법과 정책

        1) 보호기법

           - 접근제어, 이름부여(naming), 암호화(password), 해독화(cryptography), 사용자 인증

        2) 접근행렬에 의한 보호기법

           ① 전역 테이블(global table)

               - 접근행렬의 가장 단순한 구현으로 3개의 순서쌍<영역, 객체, 권한집합>들의 집합으로 구성

               - 주기억 공간에 보관 시 기억장소 낭비

               - 보조기억 장치로부터 추가적 입출력 필요

           ② 접근제어 리스트(access control list)

               - 접근행렬의 각 객체와 열을 결합하여 <영역, 권한집합>의 순서쌍을 갖는 접근 리스트로 

                 표현하는 방법

           ③ 권한 리스트(capability list) - 객체와 그 객체에 허용된 조작 리스트

           ④ Lock-Key 기법 - 접근제어리스트와 권한리스트의 절충

                             - 각 객체는 lock이라 불리는 유일한 비트 패턴 리스트를 갖고 각 영역은

                                key라는 독특한 비트열을 가지고 있다

                             - 수행중인 프로세스는 해당 영역이 객체의 lock과 일치하는 key가

                                있을 때 만 그 객체에 접근


4.2.2 보안(Security)

    (1) 개요

        1) 보안이란?

           - 컴퓨터 시스템 내에 저장된 프로그램과 데이터에 대하여 통제된 접근 방식을 어떻게 제공할

             것인가를 다루는 문제

           - 적절한 보호 시스템뿐만 아니라 시스템이 동작하는 외부 환경에 대해서도 고려

           - 시스템과 시스템 데이터가 결함 없이 보존

           - 정의된 자원에 대해 프로세스 또는 사용자의 접근을 제어

        2) 종류

           ① 외부보안 - 불법 침입자나 천재지변으로부터 시스템을 보호

             - 시설보안 : 감지기능을 통해 외부 침입자나 천재지변으로부터의 보안

             - 운용보안 : 시스템운영자, 관리자, 경영자들의 정책과 통제절차를 통해 이루어지는 보안

           ② 내부보안 - 하드웨어나 운영체제의 내장된 보안 기능을 통해 신뢰성을 유지

           ③ 사용자 인터페이스 보안 - 사용자의 신원을 운영체제가 확인하는 절차를 통해 불법 

                                       침입자로부터 시스템을 보호

     (2) 보안의 위험을 줄이는 방법

         1) 모니터 기법

            - 허락한다는 신호가 나오면 감시 프로그램이 그 파일을 액세스하고 그 결과를

               사용자 프로그램에 알려준다.

         2) 위험감시 기법

            - 중요한 작업에 대한 제어권을 사용자가 직접 갖지 못하게 하고 운영체제가 갖는 방법

            - 사용자는 운영체제에 요구만 한다.


제5장 분산 운영체제

5.1 개념 및 특징

    (1) 분산처리 시스템(distribute processing system)

        1) 분산처리 시스템이란? - 중앙으로부터 분산되어있는 컴퓨터로 모든 데이터의 처리 작업을 

                                  수행하여 그 결과를 상호 교환하도록 연결되어 있는 시스템

        2) 장점

           ① 제한된 자원의 공유 가능

           ② 시스템의 능력에 비해 업무량이 과중되어도 시스템을 바꿀 필요가 없다

           ③ 업무량 증가에 따라 컴퓨터를 네트워크에 투입하여 시스템의 성능을 향상

           ④ 하나의 컴퓨터가 고장시에도 다른 컴퓨터가 작업을 계속 수행하므로 작업에 대한 신뢰도를 

              높일 수 있다

           ⑤ 한 작업을 병렬로 처리하므로 전체적인 처리율(throughput)을 향상 시킨다

        3) 단점

           ① 분산처리 시스템에 투입되는 컴퓨터 비용 및 시스템의 구축이 쉽지 않다

           ② 여러 시스템간의 호환성을 고려하여 표준을 정해야 한다

    (2) 일반적인 형태

      1) 서브시스템을 중심으로 여러 노드들이 연결되어 있으며 각 노드에는 단말기가 설치 

      2) 통신서브 시스템 - 노드들 사이의 통신을 연결해주는 시스템으로 LAN, WAN


5.2 분산 운영체제

5.2.1 분산처리 시스템의 개발동기

        1) 자원공유(resource sharing)

           - 서로 다른 기능을 가진 많은 수의 사이트들이 서로 연결되어 있다면 한 사이트의 사용자는 

             다른 사이트의 이용 가능한 자원을 사용할 수 있다

        2) 연산속도 향상(computation speed-up)

           - 특정 연산이 동시에 수행 가능한 부분 연산들로 분할될 수 있다면 이들 연산들을 여러

             사이트에 분산시켜 연산 속도를 높일 수 있다

        3) 신뢰성(reliability)

           - 분산체제 내에서 한 사이트가 고장이 발생해도 나머지 사이트들은 계속 동작

        4) 통신(communication)

           - 다수의 사이트가 통신 네트워크를 통해 서로 연결되었을 때는 다른 사이트에 있는 사용자들이 

             정보를 서로 교환할 수 있다.

   * 분산 운영체제 구성동기(설계 이유) 기출95

      - 신뢰성 향상, 작업의 신속한 처리, 여러 자원들의 공유, DB의 공동 이용, 통신 이용


5.2.2 분산처리 시스템의 형태

    (1) 프로세서 모델에 따라

        1) 클라이언트-서버 모델 - LAN을 기본으로 구성되며 응용 프로그램이 사용자의 워크스테이션이나 

                                  PC 환경에서 수행

        2) 프로세서 풀(pool) 모델 - 응용프로그램들이 프로세서 서비스로서 관리되는 컴퓨터에서 수행

        3) 혼합모델 - 사용자의 요구와 자원처리가 매칭 된다

    (2) 위상(topology)에 의한 분류

        1) 완전 연결형 - 각 노드가 시스템내의 모든 다른 노드와 직접 연결된 상태이며 노드 및 회선에 

                         대한 비용 증가는 노드수의 제곱에 비례

                       - 전송속도가 빠르고 신뢰성이 높으나 비용이 많이 든다

        2) 부분 연결 구조 - 직접 연결되지 않은 노드가 존재하여 비용은 완전연결 구조보다 싸나 신뢰성은 

                            떨어진다

        3) 계층 구조형 = 트리 구조형 - 트리 형태로 연결되며 비용은 부분연결형보다 싸다

                                     - 부모노드가 고장나면 자식노드들은 통신이 두절

        4) 링(ring)형 = 환상형

           - 이웃 노드간의 단방향 및 양방향 통신이 가능하며 노드의 고장 발견이 쉽다

           - 보안 문제가 발생하며 새 노드 추가 시 통신회선을 절단해야하며 각 노드에서 전송지연 발생

        5) 성형(star) 구조

           - 각 노드들이 point-to-point 형태로 중앙 컴퓨터에 연결되고 중앙 컴퓨터를 경유하여 통신

           - 보수와 관리가 용이하고 노드의 고장이 다른 노드에 영향을 주지 않는다

           - 중앙컴퓨터 고장 시 전체 네트워크가 정지되며 통신망 전체가 복잡

        6) 버스(bus) 구조

           - 통신회선이 1개이므로 물리적 구조가 간단하고 노드의 추가와 삭제가 용이

           - 데이터 비밀 보장이 어렵고 통신회선의 길이에 제한이 있다

    (3) 분산 범위에 의한 분류

        1) WAN(wide area network) - 원거리 시스템을 연결하므로 통신속도가 느리고 신뢰성이 낮다

        2) LAN(local area network) - 근접 시스템을 연결하므로 속도가 빠르고 오류 발생률이 낮다

    (4) 운영체제 형태에 따른 분류

        1) 네트워크 운영체제(network operating system)

           - 각 노드가 독자적인 운영체제를 가지며 필요시 네트워크를 통해 통신

           - 설계와 구현이 쉽다

           - 자원의 공유가 번거롭고 프로세서의 운영체제가 모두 다를 때 곤란

        2) 분산 운영체제(distributed operating system)

          - 하나의 운영체제가 모든 네트워크, 프로세서 및 시스템내의 자원과 작업을 총괄

          - 사용이 편리하고 시스템간 자원공유가 쉽다

          - 설계와 구현이 어렵다


5.3 병렬처리 시스템(Parallel Processing)

5.3.1 병렬처리 시스템의 개요

    (1) 의미 - 다중처리 시스템에서 하나 또는 그 이상의 운영체제가 여러 개의 프로세서를 관리하며 동시에 

              수행하는 시스템

    (2) 병렬처리 시스템의 발전단계

        1) 1단계 - 단일 프로세서 컴퓨터에 병렬기법 도입

                 - RISC(reduced instruction set computers)

        2) 2단계 - 운영체제를 단일 컴퓨터의 운영에서 벗어나 복수의 연산소자 및 네트워크까지도 운영

                 - 알고리즘 기술 발달

        3) 3단계 - 병렬화를 묵시적으로 나타내는 새로운 언어의 개발 요구

        4) 4단계 - 사용자와 같은 레벨에서 통신할 수 있도록 높은 레벨의 사용자 인터페이스 제공


5.3.2 병렬 처리 시스템의 분류

    (1) Flyne에 의한 컴퓨터 구조의 분류

        1) SISD(Single Instruction stream Single Data stream)

           - 한번에 하나의 명령수행, 가장 일반적인 구조로 폰 노이만 방식

        2) SIMD(Single Instruction stream Multi Data stream)

           - SISD보다 빠르다, 배열처리기

        3) MISD(Multi Instruction stream Single Data stream)

           - 이론적일 뿐 실제 사용하지 않는다

        4) SISD(Multi Instruction stream Multi Data stream)

           - 진정한 의미의 병렬 프로세서(멀티 프로세서라고도 함)

    (2) 자료와 명령어의 흐름에 따른 병렬처리 시스템

        1) 파이프라인 - 하나의 프로세서를 서로 다른 기능을 가진 여러 개의 부 프로세서로 나누어

                         각 부 프로세서가 동시에 서로 다른 데이터를 취급하도록 하는 기법

                       - 한번에 여러 명령어가 실행되게 해서 성능을 향상시키는 방법

        2) 벡터(vector) - 벡터 명령어가 실행되면 벡터(피 연산자)의 각 항목들은 하나씩 파이프라인에 

                         나눠지고 파이프라인의 한 단계가 완성되는 동안 연기되는 기법

        3) 배열 처리기(array processor) - SIMD 컴퓨터로 한 배열의 각 항목에 동시에 같은 명령어를 수행

        4) 데이터 흐름 프로세서(data flow)

           - 많은 연산을 병렬적으로 수행하며 요구되는 데이터가 이용 가능한 명령어를 실행하기 때문에

             데이터 구동방식(data driven) 이라고 한다

        5) 다중 처리기(multiprocessor)

           - 기억장치나 데이터베이스 등의 자원을 공유하며 상호 작용하는 다중 프로세서들을 통하여

              비 동기적 병렬성을 얻는다

           - 2개 이상의 프로세서를 사용하므로 하나가 고장나더라도 다른 프로세서들은 가동할 수 있다

    (3) 기억장치 결합도에 따른 분류

        1) 강결합(tightly coupled)

           - 여러 프로세스가 하나의 저장장치를 공유하며 하나의 운영체제가 모든 프로세스들과 시스템

             하드웨어를 제어

           - 전송속도가 기억장치의 대역폭에 의해 결정

           - 공유 메모리를 차지하기 위한 프로세스간 경쟁이 치열

           - 결합 스위치(combining switch)로 프로세스간 경쟁 해결

        2) 약결합(loosely coupled)

           - 각 프로세스는 각자의 기억장치를 가지고 있다

           - 자체 운영체제를 갖고 있다

           - 프로세스간 통신은 메시지전달과 원격 프로시져 호출로 이루어진다

    (4) 연결방식에 따른 분류

        1) 공유버스(shared bus)

           - 프로세서, 기억장치 및 입출력 장치들간에 하나의 버스만 존재

           - 간단하며 경제적이고 융통성이 있다, 새로운 장치를 연결하기 쉽다.

           - 한번에 한가지 전송만 가능하고 버스에 이상이 생기면 전체 시스템이 중단

           - 시스템이 바빠지면 효율성이 저하된다

        2) 크로스바 교환행렬(crossbar-switch matrix)

           - 공유버스 구조에서 버스의 수를 기억장치의 수만큼 증가시킨 시스템

           - 모든 기억장치 모듈로 동시 전송이 가능

           - 하드웨어가 크고 복잡, 인터페이스는 간단

        3) 하이퍼 큐브(hypercube)

           - 비교적 경제적인 방법으로 많은 프로세서들을 연결하는 방법을 제공

           - 많은 노드가 연결될 경우 비용이 급속도로 증가

        4) 다단계 네트워크(multistage network) = 다중 입 출구 기억장치

           - 한 노드가 어떠한 다른 노드에라도 연결할 수 있도록 하여 여러 프로세서의 연결을 쉽게 한다

           - 교환기의 수가 매우 적으며 단일 경로지만 다양한 연결이 가능

           - 교환 네트워크의 비용을 증가시키며 전송 시간이 비교적 느리다

    (5) 다중처리 시스템의 운영체제 형태에 따른 분류

        1) 주/종 관계(master/slave)

           - 하나의 프로세서가 master로 지정되어 범용 프로세서로서 연산 및 입출력을 담당하고

             나머지들은 slave로 연산만을 담당하고 사용자 프로그램만 수행

           - 구현이 쉬우나 하드웨어의 비 대칭성이 발생하고 하드웨어를 최적으로 사용하지 못한다

        2) 분리수행(separate executives) 

           - 각 프로세서가 독립적으로 자원을 가지는 단일프로세서 시스템처럼 독자적인 운영체제와

             기능을 가지는 형태

           - 각 프로세서에서 발생하는 인터럽트는 해당 프로세서에서 해결

           - 주/종 관계보다 신뢰도가 높아 한 프로세서의 고장이 전체 시스템에 영향을 주지 못한다

           - 일부 프로세서가 유휴 상태로 될 수 있다

        3) 대칭처리

           - 모든 프로세서가 동등한 입장의 대칭성을 가지고 있으며 구현 및 수행이 매우 복잡한 형태

           - 가장 강력한 능력의 시스템

           - 한 운영체제를 동시에 수행할 수 있게 하므로 재진입 코드와 상호배제가 필요

           - 다른 기법에 비해 작업을 효과적으로 분산시킬 수 있다

           - 모든 프로세서들은 동등한 입장에서 입출력 장치와 기억장치를 사용

           - 기억장소를 여러 프로세스가 동시에 엑세스 하려할 경우 보통 하드웨어로 해결

           - 시스템 테이블을 여러 프로세스가 동시에 엑세스 하려할 경우 보통 소프트웨어로 해결

           - 신뢰도가 가장 높다.


제6장 운영체제의 실제

6.1 UNIX

6.1.1 기본 개념 기출95 기출96

     - UNIX 운영체제의 파일 시스템이 관리하고 있는 디렉토리 구조 : 다단계 트리구조

     - CPU 스케줄링 방식 : 기본 우선순위 지정 후에 우선순위 조정

     - I-node : 파일에 할당된 data list의 I번째 node를 의미

     - 파이프(pipe) : UNIX에서 프로세스간의 통신과 동기를 위해 사용

'연구개발 > Etc..' 카테고리의 다른 글

mac port kill  (0) 2024.01.31
[Docker] 생성 및 실행  (0) 2018.07.04
지표 관련 용어  (0) 2016.08.22
unity key  (0) 2016.05.07
RAID 1+0 과 0+1의 차이점  (0) 2011.07.11

R에서 파이썬까지…데이터과학 학습 사이트 8

 

1. 데이터과학 입문

코세라 / 워싱턴대 데이터과학 입문

 

 

2. R, Python 프로그래밍

데이터캠프 / R 입문

 

코드카데미 파이썬

구글 파이썬 클래스

 


 

3. 기계 학습

코세라 / 스탠포드 머신 러닝 / 앤드류 응

 

4. 통계학

유튜브 / 프린스턴대 통계 1

 

5. 데이터 시각화

D3 튜토리얼 / 스콧 머레이 블로그

 

 

 

보다 심도 있는 강좌들 및 기타 데이터 과학 오픈소스 강좌가 알고 싶다면, 다음의 웹페이지를 참고하자.

깃허브 : 데이터 사이언스 마스터즈

 

출처 : http://www.bloter.net/archives/237013



출처: http://extraman.tistory.com/400 [맨땅에 헤딩하기]

출처: http://www.dbguide.net/knowledge.db?cmd=specialist_view&boardUid=168680&boardConfigUid=92&boardStep=&categoryUid

 

 

아는 사람은 다 아는 모르는 사람은 절대 모를 R에 대한 것들

 

 

R에 대한 도움 얻기

stackoverflow.com : 프로그래밍에 대한 질문

crossvalidation.com : 통계에 대한 질문

R-Help mailling lists : stat.ethz.ch/mailman/listinfo의 r-help

대부분 구글에서 질문을 질의하면 r-help로 연결을 해준다.

 

필요한 함수 찾기

help.search(“apriori”) 또는 ??apriori

또한 sos 패키지를 활용해서 찾아볼 수 있다.

install.packages("sos")

library(sos)

findFn("apriori") # 혹은 ???apriori

RSiteSearch()함수의 일부 기능을 하는 함수로서 http://search.r-project.org/ 의 결과를 data.frame으로 반환하는데이를 출력하면 html페이지로 웹브라우저를 통해 보여준다하지만 좀더 자세한 결과를 보고 싶다면 RSiteSearch()함수를 사용하는 걸 추천한다

패키지를 로딩했으나 어떤 함수가 있는지 궁금할때는 아래 명령어를 사용한다.

help(package="arules")

 

함수 동작 방식 살펴보기

“::”연사자를 이용한 패키지 내부 함수 살피기

R > KoNLP::HangulAutomata

function (input, isKeystroke = F, isForceConv = F)

{

if (!is.character(input) | nchar(input) == 0) {

stop("Input must be legitimate character!")

}

if (isKeystroke) {

if (!exists("KoKeystrokeAutomata", envir = KoNLP:::.KoNLPEnv)) {

assign("KoKeystrokeAutomata", .jnew("kr/pe/freesearch/korean/KoKeystrokeAutomata",

isForceConv), KoNLP:::.KoNLPEnv)

}

keyAuto <- get("KoKeystrokeAutomata", envir = KoNLP:::.KoNLPEnv)

KoHangulAuto <- .jcast(keyAuto, "kr/pe/freesearch/korean/KoHangulAutomata")

}

else {

if (!exists("KoJamoAutomata", envir = KoNLP:::.KoNLPEnv)) {

assign("KoJamoAutomata", .jnew("kr/pe/freesearch/korean/KoJamoAutomata",

isForceConv), KoNLP:::.KoNLPEnv)

}

JamoAuto <- get("KoJamoAutomata", envir = KoNLP:::.KoNLPEnv)

KoHangulAuto <- .jcast(JamoAuto, "kr/pe/freesearch/korean/KoHangulAutomata")

}

.jcall(KoHangulAuto, "V", "setForceConvert", isForceConv)

out <- .jcall(KoHangulAuto, "S", "convert", input)

.jcall(KoHangulAuto, "V", "clear")

Encoding(out) <- "UTF-8"

return(out)

}

<environment namespace:konlp=""></environment>

패키지가 로딩되어 있다면 단수히 함수명만 명시함으로써 내부 코드를 살펴볼 수 있다.

만일 패키지 내부의 숨겨진 함수를 확인하고 싶다면 “:::”연산자를 사용하면 접근 가능하다.

R > KoNLP:::.onLoad

function (libname, pkgname)

{

ret <- .jinit(parameters = "-Dfile.encoding=UTF-8")

if (ret < 0) {

stop("Could not create VM.")

}

else {

packageStartupMessage("Java initialized.")

}

.jpackage(pkgname, lib.loc = libname)

}

<environment namespace:konlp=""></environment>

대부분 코드로 함수가 작성되어 있는 경우 이런 방법으로 확인 가능하다그러나 고전적인 코드의 경우 포트란 혹은 C로 작성이 되어 있을 경우가 많고 필자의 경우 텍스트 마이닝 코드는 자바로 작성하였는데 이에 대한 확인을 하기 위해서는 패키지 소스코드 전체를 볼 필요가 있다이 경우에는 CRAN에서 제공하는 tar.gz으로 묶인 패키지 파일을 풀어보는게 필요하다.

올바른 함수코드 작성하기

R에서 함수 작성은 크게 어렵지 않으나 함수코드를 작성하는데 어느정도 규약을 지켜주는게 필요하다.

일단 함수 들여쓰기의 경우 RStudio의 편집기를 쓰면 좋은데이는 RStudio가 코드 작성에는 최적이기 때문이다. R함수의 경우 한 라인이 길어질 가능성이 많기 때문에 들여쓰기의 경우 2개 공백 정도가 적당하며 물론 tab문자의 크기도 2개 공백이 좋다게다가 빈번히 주석을 달아줄 필요가 있는데또한 RStudio에서 편리한 옵션들을 제공한다.

다른 사람들의 함수를 읽어볼 필요가 있을때는 formatR패키지에서 제공하는 tidy.dir() 함수를 사용하면 좋은데한 가지 단점은 이를 한글 윈도우에서 동작시키면 모든 한글이 깨진다는 문제가 있다따라서 주의를 요한다.

R에 대한 코딩 가이드도 존재하는데,

http://google-styleguide.googlecode.com/svn/trunk/google-r-style.html

https://github.com/hadley/devtools/wiki/Style

위 두 페이지는 꼭 한번 읽어볼만 한 페이지들이다.

디버깅하기

에러가 나면 가장 먼저 확인해야 될 명령어는 아마도 traceback()일 것이다이 명령어는 call stack을 추적해 에러가 난 함수 호출을 출력해 준다이를 통해서 어느 함수에서 에러가 난 것인지 확인할 수 있다.

browser()라는 함수가 있는데이 함수는 다른 디버그 기능과 함께 쓸 때 가치를 발휘한다예를 들어 본인의 함수에서 특정 부분에 print()문을 넣어서 디버깅 하고 싶은 부분이 있다면, browser()라는 함수를 자신이 디버깅 하고 싶은 코드 중간에 삽입해서 print()문을 대신하게 할 수 있다함수실행시 browser()함수를 만나게 되면 browser 모드로 들어가게 되며 흡사 gdb의 디버깅 화면을 연상하게 하는 행동을 할 수 있다예를 들어 browser()코드가 들어간 부분이 실행되는 당시의 모든 객체를 보고자 한다면 objects()함수를 실행하면 객체 리스트를 볼 수 있으며 해당 객체명을 입력하면 객체에 담겨진 데이터를 출력해 볼 수 있다.

이외에 browser()와 함께 동작하는 debug(), options(error=recover), trace()와 같은 함수들이 있는데이들에 대해서는 추후 시간이 되면 정리해 공유하도록 하겠다.

즐거운 소식은 RStudio가 추후 디버깅에 대한 기능을 IDE에 추가할 예정이니 독자들은 이 툴을 기대해 보는 것도 좋을거 같다.

소스코드 관리

R로 만들어진 소스코드 파일은 관리 대상이다.

개발자가 아닌 대부분의 R사용자들은 SVN과 Git에 대해서 어려움을 가지고 있을 것인데자신의 코드가 관리되고 발전이 되길 원한다면 반드시 이런 형상관리 툴 정도는 간단하게나마 다룰 수 있어야 된다.

RStudio가 Git과 SVN에 대한 인터페이스를 제공하고 있으니 이를 활용하는 것도 좋고이것들이 어렵다면 dropbox와 같은 공유 드라이브 애플리케이션을 사용해도 좋을 것이다역시 이 부분도 방대한 양이기 때문에 추후 기회가 되면 정리해 보겠다.

소스코드 관리

필자의 경우 분석 리포트를 작성하거나혹은 컬럼을 쓰거나 하는 등의 데이터를 다루는 모든 일은 프로젝트로 관리한다.

되도록 코드와 문서는 함께 관리되게 끔 하고 언제든지 문서를 생성할 수 있게끔 만들어 둔다. Latex을 사용할 수 있는 사용자는 knitr나 Sweave와 같은 패키지를 통해 쉽게 분석 관련 문서를 관리할 수 있으며이것이 힘든 분들은 R Markdown을 사용해 관리하면 된다.

그리고 모든 데이터 생성은 원본 데이터를 기반으로 생성되게끔 해준다이는 원본을 훼손 시키지 않으려는 노력 이상의의미를 가지고 있고 원본에서 어떻게 전처리된 데이터를 생성하게 끔 하는지 그 과정도 굉장히 중요하기 때문이다. 만일 원본 데이터가 정말 크다면 전처리된 적은 데이터를 가지고 있으며 이를 어떻게 생성했으니 전처리 과정도 기술해서 남겨야 할 것이다.


'Program > R' 카테고리의 다른 글

Rstudio package 설치시 에러  (0) 2017.09.10

파이썬 가상환경 설정에 대한 이전 글이 있지만, VirtualEnvWrapper 툴을 이용하여 가상환경을 설정하는게 더 편한거 같아 이 방법도 올린다.

 

pip 설치

$ sudo apt-get install python-pip

 

virtualenvwrapper 설치

$ sudo pip install virtualenvwrapper    // virtualenv 도 설치 된다.

 

가상 환경을 저장할 디렉토리를 생성하고, 환경변수에 등록

$ mkdir ~/.virtualenvs         //  .virtualenvs 라는 디렉토리 생성

 

~/.bashrc 파일 마지막에 아래 내용을 적어줌.

export WORKON_HOME=~/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

 

바뀐 .bashrc 파일 적용

$ source .bashrc

 

가상환경 생성

mkvirtualenv [가상환경 이름]     //  이렇게 사용한다.

$ mkvirtualenv py2     // py2 라는 가상환경을 생성했다.

프롬프트 앞에 (py2)가 붙을 것이다. 그래도 제대로 생성되었는지 확인해보자

(py2)~$ which python

/home/user_name/.virtualenvs/py2/bin/python  이라고 나오면 정상적으로 생성된것이다.

 

py2 가상환경에서 빠져나오려면,

(py2)~$ deactivate

다시 py2 가상환경에 접속하려면

$ workon py2

 

파이썬3 버전의 가상환경도 만들어 주자.

$ mkvirtualenv py3 –-python=python3     //  python3 버전의  py3라는 가상환경을 생성.

프롬프트 앞에 이번에는 (py3)가 붙어 있을것이다.  마찬가지로 제대로 생성되었는지 확인.

(py3)~$ which python

/home/user_name/.virtualenvs/py3/bin/python  라고 나온다.  제대로 되었다.

 

python2, python3 버전의 py2, py3 라는 가상환경을 설정하였다. 이제부터는 가상환경에 접속해서 작업하면 된다.



가상환경 기본 사용법

* 가상환경 접속

$ workon 가상환경 이름     // py2 나 py3 등 본인이 만든 가상환경 이름

* 가상환경 종료

$ deactivate

* 가상환경 목록

$ lsvirtualenv

* 가상환경 삭제

$ rmvirtualenv



  • 가상환경 종료
    deactivate
  • 가상환경 디렉토리로 이동
    cdvirtualenv
  • 현재 가상환경의 써드 파티 패키지 전체 삭제
    wipeenv
  • 가상환경 목록
    lsvirtualenv
  • 가상환경 삭제
    rmvirtualenv
  • 모든 가상환경에 대한 명령 실행
    # allvirtualenv command with arguments
    allvirtualenv pip install -U pip


'연구개발 > Linux' 카테고리의 다른 글

AWS EC2 (AMI)에 Java, Scala, Spark, Kafka, MongoDB, Redis, Node.js, Maven 설치  (0) 2017.12.29
centos fdisk  (0) 2017.03.30
ubuntu 방화벽  (0) 2016.03.14
zabbix mail setting  (0) 2016.03.03
swap  (0) 2016.03.02

리눅스 용량 확장 명령어 resize2fs 사용법 (Nothing to do! 나올때)

출처: http://vitta.tistory.com/25 [Cloud]



EC2 의 CENTOS 의 경우 8G 정도의 Root 볼륨이 할당됩니다. 약간 작아 20G로 resize2fs 시켜 사용중이었는데 6.7 버전부터 resizefs /dev/xvda1 을 하면 

The filesystem is already 2096896 blocks long.  Nothing to do!

라는 메세지가 발생합니다.

이를 해결하기 위해 아래의 방법을 실행합니다.

 이는 시작 섹터를 변경하여  이전 파티션을 삭제하고 동일한 파티션 번호를 새로 생성하게 하는 것입니다. 잘못될 경우 부팅에 실패할 수 있으므로, 사용 중인 시스템에서는 백업이 필수라 여겨집니다. 


[root@cateye ~]$ lsblk 

NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT

xvda    202:0    0  20G  0 disk 

└─xvda1 202:1    0   8G  0 part /

[root@cateye ~]# resize2fs /dev/xvda1

resize2fs 1.41.12 (17-May-2010)

The filesystem is already 2096896 blocks long.  Nothing to do!


[root@cateye ~]# resize2fs /dev/xvda

resize2fs 1.41.12 (17-May-2010)

resize2fs: Device or resource busy while trying to open /dev/xvda

Couldn't find valid filesystem superblock.

[root@cateye ~]# df -h

Filesystem      Size  Used Avail Use% Mounted on

/dev/xvda1      7.8G  943M  6.5G  13% /

tmpfs           938M     0  938M   0% /dev/shm

[root@cateye ~]# fdisk /dev/xvda


WARNING: DOS-compatible mode is deprecated. It's strongly recommended to

         switch off the mode (command 'c') and change display units to

         sectors (command 'u').


Command (m for help): u

Changing display/entry units to sectors


Command (m for help): p


Disk /dev/xvda: 21.5 GB, 21474836480 bytes

255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk identifier: 0x00057cbb


    Device Boot      Start         End      Blocks   Id  System

/dev/xvda1   *        2048    16777215     8387584   83  Linux


Command (m for help): d

Selected partition 1


Command (m for help): n

Command action

   e   extended

   p   primary partition (1-4)

p

Partition number (1-4): 1

First sector (63-41943039, default 63): 2048

Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): ENTER

Using default value 41943039


Command (m for help): p


Disk /dev/xvda: 21.5 GB, 21474836480 bytes

255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk identifier: 0x00057cbb


    Device Boot      Start         End      Blocks   Id  System

/dev/xvda1            2048    41943039    20970496   83  Linux


Command (m for help): a

Partition number (1-4): 1


Command (m for help): w

The partition table has been altered!


Calling ioctl() to re-read partition table.


WARNING: Re-reading the partition table failed with error 16: Device or resource busy.

The kernel still uses the old table. The new table will be used at

the next reboot or after you run partprobe(8) or kpartx(8)

Syncing disks.


[root@cateye ~]# reboot


Broadcast message from root@cateye



[root@cateye ~]$ lsblk 

NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT

xvda    202:0    0  20G  0 disk 

└─xvda1 202:1    0  20G  0 part /

[root@cateye ~]$ df -h

Filesystem      Size  Used Avail Use% Mounted on

/dev/xvda1       20G  947M   18G   5% /

tmpfs           938M     0  938M   0% /dev/shm



위의 내용은 제가 직접 실행한 내용이고, 아래에 설명을 따라했습니다. 가급적이면 원본 사이트에가서 참조하시기 바랍니다.



To expand on JD's self-accepted answer, here's exactly what to do:

df -h #print the name of your boot partition

lsblk #show info on all your block devices

You'll see from that output what the name of the disk is of your root partition. For example, you probably see something like this:  xvde 202:64 0 32G 0 disk └─xvde1 202:65 0 8G 0 part /

Our goal is to make xvde1 use the whole available space from xvde. Here's how your resize your partition:

fdisk /dev/xvda (the disk name, not your partition) This enters into the fdisk utility.

  1. u #Change the display to sectors
  2. p #Print info
  3. d #Delete the partition
  4. n #New partition
  5. p #Primary partition
  6. 1 #Partition number
  7. 2048 #First sector
  8. Press Enter to accept the default
  9. p #Print info
  10. a #Toggle the bootable flag
  11. 1 #Select partition 1
  12. w #Write table to disk and exit

Now, reboot your instance: reboot

After it comes back do:

resize2fs /dev/xvde1 (the name of your partition, not the block device)

And finally verify the new disk size: df -h

1 출처는 여기

http://stackoverflow.com/questions/26770655/ec2-storage-attached-at-sda-is-dev-xvde1-cannot-resize



출처: http://vitta.tistory.com/25 [Cloud]

https://hunkim.github.io/ml/


모두를 위한 머신러닝과 딥러닝의 강의

알파고와 이세돌의 경기를 보면서 이제 머신 러닝이 인간이 잘 한다고 여겨진 직관과 의사 결정능력에서도 충분한 데이타가 있으면 어느정도 또는 우리보다 더 잘할수도 있다는 생각을 많이 하게 되었습니다. Andrew Ng 교수님이 말씀하신것 처럼 이런 시대에 머신 러닝을 잘 이해하고 잘 다룰수 있다면 그야말로 "Super Power"를 가지게 되는 것이 아닌가 생각합니다.

더 많은 분들이 머신 러닝과 딥러닝에 대해 더 이해하고 본인들의 문제를 이 멋진 도구를 이용해서 풀수 있게 하기위해 비디오 강의를 준비하였습니다. 더 나아가 이론에만 그치지 않고 최근 구글이 공개한 머신러닝을 위한 오픈소스인 TensorFlow를 이용해서 이론을 구현해 볼수 있도록 하였습니다.

수학이나 컴퓨터 공학적인 지식이 없이도 쉽게 볼수 있도록 만들려고 노력하였습니다.

 시즌 RL - Deep Reinforcement Learning

비디오 리스트 (일주일에 한강좌씩 천천이 업데이트 예정입니다.)

시즌 NLP - Deep NLP

(시즌 RL이 끝나는 2017년 4~5월경에 업데이트 예정입니다.)

시즌 1 - 딥러닝의 기본 (TF 1.0 lab 업데이트중) 비디오 리스트

Acknowledgement

이 비디오는 저도 인터넷등을 통해 공부하면서 만든것이며 아래 자료를 많이 사용하였습니다.

의견주기

비디오나 강의에 대한 의견이 있으시면 아래로 이메일을 보내 주시면 됩니다. 홍콩과기대 김성훈

이번에는 선형대수학(Linear algebra)에 대해서 공부를 합니다.

이름은 거창하지만 실제로는 더하기, 곱하기 이런 기본 산수 수준인데 단지 다른 것은 알고리즘을 사용하기 위해서 필요한 행렬과 벡터 위주로 다루고 있습니다.


행렬이나 벡터도 이름만 거창하지 실제로는 여러번 산수해야하는 것을 한번에 산수하면 되도록 해주는 도구라고 생각하면 될 것 같습니다. 알아두면 매우 유용한 면이 많아 보이는 내용입니다.


예를 들어서, 1+1, 1+2, 1+3을 한다고 생각해보겠습니다.

단순한 더하기를 3번 수행해야 하는데, 행렬이나 벡터를 이용하면 더하기 1번에 3개의 결과를 얻어낼수 있는 효과가 있을 뿐이지 더하기는 동일합니다.



행렬(Matrix)


사각형 모양안에 숫자들을 나열해 놓은 형태로 아래 그림과 같이 표기가 됩니다.

이 숫자들은 행(rows)과 열(columns)로 구분이 가능합니다. 그래서 전체를 하나로 표기할 수도 있고 내부에 숫자들을 각각 표기할 수도 있게 됩니다. 

Matrix를 표기할 때 4 x 2와 같이 표기를 합니다. 그냥 4개의 행과 2개의 열로 이루어진 Matrix이며 4 by 2라고 읽습니다.

아래 그림에서는 R로 Matrix의 이름을 표현했고 4x2의 숫자를 갖는 매트릭스를 보여주고 있습니다. 그리고 그 오른쪽에는 2x3의 다른 Matrix를 표현하고 있는 것입니다.




Matrix는 여러 숫자들을 가지고 있고 각자의 자리가 있기 때문에 개별적으로 요소들도 표기가 가능합니다.

아래 그림의 A라는 Matrix는 4x2의 크기를 갖고 있으며 총 8개의 숫자를 표현하고 있습니다.

A11은 1번째 행의 1번째 열의 자리에 있는 숫자를 표현합니다. 그래서 A11의 값은 1402가 됩니다.

A32는 3번째 행의 2번째 열의 자리에 있는 숫자를 표현하는 것이니 값이 1437이 되겠지요

그런데 A43은 4번째 행의 3번째 열의 자리를 찾는데 3번째 열이 없기 때문에 error가 됩니다. 존재하지 않는 값을 찾고 있기에 오류이지요




벡터(Vector)


Vector는 행렬과 비슷하게 생겼지만 다른 점은 열(column)이 1개만 존재하는 형태라는 것입니다. 그래서 항상 한줄로만 표기가 됩니다. 즉, n x 1의 matrix 이면서 vector가 되는 것입니다.

아래 그림에서는 Vector를 y로 표기하였습니다.

마찬가지로 각 숫자들은 지정 좌석이 있기 때문에 y1은 1번째 자리의 460의 값을 표현할 수 있게 됩니다.


1번째 자리수는 0번부터 시작할 수도 있고 1번부터 시작할 수도 있습니다.

이것은 사용하는 program에 따라 다를 수 있습니다. 일반적인 java와 c 같은 프로그램에서는 배열을 보통 0부터 표현을 하기도 하며 (0-indexed), 이 강좌에서는 1부터 표현하는 것으로 교수님께서 설명을 하고 계십니다. (1-indexed)


4개의 숫자이므로 0-indexed에서는 y0, y1, y2, y3으로 표현이 되고, 1-indexed에서는 y1, y2, y3, y4로 표현이 되는 차이만 있을뿐입니다.




Matrix Addition(행렬 더하기)


Matrix와 Vector의 정의를 알았으니 이제 더하는 방법을 알아봅니다.

두개의 Matrix를 더하는 것은 같은 자리의 숫자를 더해서 새로운 Matrix를 만들어 내는 것입니다.

아래 그림에서 3x2 Matrix+ 3x2 Matrix를 하면 같은 사이즈를 가지는 3x2 Matrix가 생성된다는 것을 보여주고 있습니다.


같은 자리의 수인 1 + 4 = 5,  0 + 0.5 = 0.5,  2 + 2 = 4와 같이 더하기가 되는 것을 알 수 있습니다.

그 밑에 있는 3x2 Matrix + 2x2 Matrix는 왜 error가 될까요? 숫자들의 자리가 맞지 않으니 더할 수 있는 값이 없어서 입니다. 그러므로 같은 크기의 Matrix끼리만 연산이 된다는 결과가 나타납니다.




Scalar Multiplication ( Matrix 곱하기 상수)


Scalar는 상수를 의미합니다. 이 상수를 Matrix에 곱하는 것이 가능합니다. 같은 크기의 Matrix가 아니지만 각각의 숫자들에 동일하게 적용시켜주면 됩니다.


아래 그림에서 Matrix에 3을 곱해주면 각 자리에 위치한 모든 숫자들에 3을 곱해서 기존 Matrix의 크기와 같은 Matrix가 생성이 되는 모습입니다. 앞에서 곱해주나 뒤에서 곱해주나 같은 결과가 나옵니다. 산수와 같죠?

그 밑에 쪽에 나누기도 동일하게 적용을 해주면 연산이 가능합니다.




지금까지 알아본 더하기와 곱하기를 혼합해서 연산을 하면 아래 그림과 같이 됩니다.

곱하기와 나누기를 먼저 계산하고 그 결과를 더하기와 빼기를 수행합니다. 이것도 산수와 똑같습니다.




Matrix X Vector (Matrix 곱하기 Vector)


Matrix와 Vector를 곱하면 어떻게 될까요

각각 크기를 가지고 있으므로 곱하기가 되는 대상에 주의를 해야 합니다.

아래 그림은 기본적인 곱하기에 대한 특성을 보여주고 있습니다. A Matrix의 크기가 m x n이라고 할 경우에 x Vector의 크기는 n x 1이 되어야 한다 입니다. 같은 사이즈의 n이 되어야 곱하기를 할 수 있다는 뜻이됩니다. 이렇게 곱하기를 한 결과는 m의 크기를 갖는 Vector가 됩니다. 그럼 어떻게 곱하기가 되는지 예제를 보면 쉽습니다.




A Matrix는 3x4의 크기를 가지고 있습니다. 4개의 columns를 가지고 있고 곱하고자 하는 x Vector는 4x1의 크기를 가지고 4개의 rows를 가집니다. 곱하기를 하는 방법은 A Matrix의 가로줄과 x라는 이름의 Vector의 세로줄을 곱해주고 이 값들을 모두 더해줍니다 . 

A11 * x1 + A12 * x2 + A13 * x3 + A14 * x4와 같이 연산이 되어 결국 값은

1*1 + 2*3 + 1*2 + 5*1   = 1 + 6 + 2 + 5   = 14 값이 되는 것입니다.

결과 값을 차례대로 Vector 형식으로 적어주면 m개의 크기를 갖는 결과 Vector가 생성이 됩니다.


이와 같이 연산이 되기에 Matrix의 가로 크기와 Vector의 세로 크기가 같아야 하겠습니다. 그리고 그 결과는 Matrix 의 세로 크기와 같은 크기를 갖는 Vector로 만들어집니다.



복잡한 식도 심플하게 변형 (kind of trick)


Matrix의 연산에 특성을 이용하면 복잡한 계산식을 심플하게 표현할 수 있게 됩니다. 이것은 parameters이 많아질수록 더욱 효과적으로 표현이 가능해지는 장점을 가지고 있습니다. 우리가 앞으로 다뤄야 하는 dataset이 아주 많은 데이터 parameters들을 가지고 있기 때문에 이를 활용하는 것에 익숙해져야 하기 때문입니다.


이전에 본적이 있는 일차방정식으로 표현이 된 h 함수입니다. 두개의 parameters를 가지고 있고 곱하기와 더하기로 표현이 되고 있습니다. 이것을 Matrix로 표현을 하면 아래쪽에 있는 그림과 같이 표현이 가능합니다.

세타zero로 표현했던 -40의 값은 상수이기 때문에 1을 곱해줘도 같은 값을 가질 수 있습니다. 세타one으로 표현했던 0.25의 값은 x와 곱해지는 인수임을 유의해서 아래 그림을 보면 됩니다.


h 함수는 집의 사이즈에 따른 집의 가격을 나타내는 공식이였습니다. x는 집의 사이즈 데이터가 되고 h는 그 사이즈에 해당하는 집의 가격을 나타냈었습니다. 이 공식에 의하면 집의 사이즈에 0.25를 곱하고 -40을 더하면 집에 가격이 된다고 합니다. 이것을 Matrix로 아래와 같이 변환해서 계산을 해보면 일차방정식과 동일한 결과가 된다는 것을 알 수 있습니다.


h 함수는 다음과 같이 표현이 가능하게 되고

h = -40 * 1 + 0.25 * x

그리고 이것은 다음과 같은 행렬의 곱으로 표현이 가능합니다.

h = [-40, 0.25] * [1, x]

이러한 원리로 분리해서 만들어낸 것입니다. (2번째 Vector를 세로로 써야 맞는데...)


아래 그림에서는 곱하는 순서만 바뀌었을 뿐이지 같은 방식의 곱하기를 나타내고 있습니다.

결국 이렇게 Matrix를 이용하면 어떻게 되는가 하면, h 함수가 다음과 같이 심플해지게 됩니다.


h = Xa (X : Matrix, a : Vector) 

상수들이 Vector가 되면서 곱하기로만 표현이 됩니다. 여기서 주의할 것은 X Matrix의 columns의 수와 a Vector의 rows 수가 같아야 연산이 된다는 것입니다.




Matrix x Matrix (Matrix 곱하기)


Matrix 끼리의 곱셈입니다. column만 늘어나는 것이고 연산은 동일합니다.

아래 그림은 m x n Matrix와 n x o Matrix를 곱하면 m x o Matrix가 결과가 된다는 것을 이야기 합니다.




아래 그림은 예를들어서 설명을 하고 있습니다.

앞에 Matrix의 가로줄과 뒤에 Matrix의 세로줄의 수들을 곱하고 그결과를 더해서 나온 값이 결과 Matrix가 됩니다.

즉, 1번째 row와 1번째 column이 연산되어, 결과 Matrix의 1번째 row와 1번째 column의 자리에 위치하는 값이 되는 것입니다.




다수의 공식도 심플하게 변형 (kind of trick)


다시 h 함수로 돌아가보겠습니다.

아까전에는 parameters를 심플하게 표현했었는데 이번에는 여러개의 h 함수를 표현해보려 합니다.


머신러닝에서 우리의 목표는 cost가 가장 적은(0에 가까운) h 함수의 찾아내는 것이였습니다.

그러기 위해서 parameters를 동시에 업데이트 해가면서 cost를 산출하고 목표를 향해 갔었습니다.

parameters가 변경되면 다른 h 함수가 되기 때문에 여러번의 연산을 하게 될 것입니다.


이것을 아래 그림과 같이 parameter를 이제 Vector가 아닌 Matrix로 표현을 하면 여러번의 연산도 한번에 심플하게 할수 있다는 것을 알수 있습니다.




Properties of Matrix (특성)


Matrix의 곱셈은 순서가 바뀌면 다른 결과가 나오므로 일반적으로는 곱하는 순서가 중요합니다.

즉, 교환법칙이 성립하지 않는다고 합니다.(not commutative)


아래 그림의 예제를 보시면 다른 결과가 나오는 것을 보실수 있습니다.

Matrix x scalar 값은 교환법칙이 성립이 되었었는데, Matrix x Matrix는 그렇치 않으니 주의를 해야겠습니다.




곱셈에서 결합법칙이 성립이 됩니다. (Associative)

산수할때 괄호안에 있는 계산이 우선순위가 되는 것과 동일합니다.




Identity Matrix라고 하는 것인데 산수에서 8 * 1 = 8이 되는 것과 동일한 결과를 나타내주는 숫자 1과 같은 역활을 하는 Matrix를 의미합니다. 이 Matrix는 대각선으로 1의 값을 갖는 형태로 표현이 됩니다. 아래 그림을 보면 Matrix의 크기별로 형태를 볼 수 있습니다. 이 Identity Matrix는 I라고 표기하며 A * I = I * A = A의 결과가 됩니다.


특이한 점은 일반적으로 Matrix 의 곱셈은 교환법칙이 성립되지 않치만 Identity Matrix 는 교환법칙이 성립된다는 점입니다.




Inverse Matrix는 어떤 Matrix 와 반대 성향을 가지고 있는 Matrix 로서 이 두개의 Matrix 의 곱셈은 Identity Matrix 로 나타나는 것입니다. 아래 그림에서 A Matrix 에 대해서 A-1 라는 Inverse Matrix 가 존재하며 이 둘을 곱하면 I Matrix가 되는 것을 보여주고 있습니다. 하지만 모든 Matrix가 Inverse 형태를 갖는 것은 아니라고 합니다. 모든 요소가 0으로 구성되는 Matrix는 Inverse를 가지지 않습니다. 


Inverse Matrix는 Identity Matrix를 만들기 위한 역산으로 계산이 되어 만들어집니다. 아래 그림의 상단에 표기된 분수처럼 계산이 되어 생성이 되는데 실제 구현할때는 이를 계산해주는 함수들이 있으니 개념만 알고 넘어가면 됩니다.




Matrix Transpose는 어느 Matrix의 크기를 변형하는 방법입니다.

아래 그림에서 A Matrix 는 2x3의 크기를 가지고 있습니다. AT라고 표시되어 있는 오른쪽에 Matrix 는 A Matrix 의 transpose라고 하고 이 Matrix 값들은 대칭이 되는 형태로 표현이 됩니다.


A Matrix의 값들을 오른쪽 아래방향으로 대각선을 그어서 이 대각선을 기준으로 거울에 비치듯이 뒤집으면 됩니다.

각각의 값들은 변하지 않고 자리만 변경되는 것입니다. 그래서 m x n Matrix의 transpose는 n x m의 크기로 변형이 됩니다.


이것은 Matrix곱하기를 할 때 유용하게 사용할 수 있습니다. 일반적인 곱셈을 할 때 크기가 동일해야 했습니다. 즉, A Matrix의 rows의 숫자들 갯수와 B Matrix의 columns의 숫자들의 갯수가 동일해야 연산이 가능했었습니다. 이 크기를 맞춰주기 위해서 형태를 transpose하고 연산을 수행하는데 이용되는 것입니다.




이것이 Linear algebra의 전부는 아니지만 우리가 머신러닝을 배우면서 사용하게 될 내용들에 대해서 배웠습니다. 이제 우리는 많은 데이터들을 한번에 처리할 수 있는 준비가 된 셈입니다.



지난번에 Cost 함수에 대해서 알아보았습니다.

이번에는 Cost 함수를 minimizing 하기 위한 알고리즘에 대해서 알아보겠습니다.

이 알고리즘의 이름은 Gradient descent algorithm이라고 합니다. 변역해서 이야기 하면 경사면을 하강하는 알고리즘이 되는데 실제로도 그렇습니다.


우리는 기본이 되는 linear regression에서 하나씩 살펴보고 있지만 실제로 이 알고리즘은 여러 다양한 분야에서 범용적으로 사용이 되는 알고리즘입니다. 중요하다는 뜻이 되겠습니다.


Cost 함수를 minimizing하기 위한 방법중에 하나인 이 Gradient descent algorithm은 이미 알고 계시듯이 우리가 목표로 하는 직선을 찾기 위한 방법이되고 이를 머신이 학습한다고 표현합니다.


현재까지 배운것을 아래와 같이 요약정리 할 수 있습니다.

Cost 함수인 J함수는 두개의 parameters를 가지고 있으며 우리가 원하는 목표는 이 Cost가 minimization되는 파라미터로 구성된 함수를 찾는 것입니다. 이 함수를 찾을때까지 우리는 두개의 파라미터를 변경해 가면서 J함수를 줄여가도록 할 것입니다.




J함수를 3차원으로 그려보면 아래와 같이 나타나는 경우도 있을 것입니다.

봉우리가 2개이상이 있는 그래서 골짜기 같은 것도 보여지는 함수인가 봅니다.

여기서 왼쪽 봉우리 쯤에서 시작을 한다고 생각을 해보면 경사면을 따라서 하강을 한다고 했으니 아래와 같은 경로로 내려와서 최저점에 도달하게 될 것입니다.




만약, 조금 다른 위치에서 시작한다고 가정을 해보면 위와는 다른 경로로 최저점에 도달한다는 것을 볼 수 있습니다.

결국 최저점이 다른 2개의 지점으로 생기게 되는군요. 이러면 안될거 같은데 뭔가 이상합니다. 이러한 최저점을 local optimum 혹은 local minimum 이라고 합니다. 우리가 원하는 목표는 global optimum 이겠지요?




위의 함수를 수학적으로 표현을 해보면 아래와 같습니다.

여기서 등호 비슷한 := 이 표현은 프로그램의 할당(Assignment)와 같습니다. 즉, 기호 오른쪽의 값(value)을 왼쪽의 항목에 할당(준다)한다는 의미로 오른쪽의 값과 동일한 값을 왼쪽 항목이 가지게 됩니다. 그냥 값을 오른쪽에서 왼쪽으로 전달해주는 겁니다.


그리고 빨간색으로 표기된 알파는 learning rate라고 합니다. 이것은 경사면을 따라 내려올때 한 걸음에 해당하는 step을 나타내는 기호입니다. 이 값이 크면 한걸음의 보폭이 커질 것이고, 작아지면 총총걸음이 되는 것과 같습니다.


그다음에 알파 뒤에 있는 구분은 고등학교때 배운 미분(편미분)인데 이것은 뒤에서 설명을 하게 됩니다. 그냥 J함수를 미분을 하는가 보다 생각하면 됩니다.


여기서는 경사면을 따라서 한걸음 내려오는 행위를 수학적으로 생각하면 두개의 파라미터인 세타zero와 세타one의 값이 변경되면서 Cost가 한단계 줄어드는 것과 같습니다. 그런데 Cost 함수(J)는 두개의 파라미터를 가지고 있기 때문에 두개의 파라미터 값이 동시에 변경되고 Cost가 산출이 되어야 합니다. 이것을 Simultaneous update라고 합니다. 




만약에 아래 그림의 오른쪽으로 나타낼 수 있는것처럼 세타zero가 값이 먼저 바뀌고 Cost를 구하게 된 이후에 세타one의 값이 바뀐다고 하면 어떻게 될까요? Cost 함수가 하나의 파라미터 값만 바뀌고 움직이고 또 다른 하나의 파라미터 값이 바뀌고 또 움직이고 마치 짝다리 걸음을 하는 것 같은 이상한 모양새가 될 것 같습니다. 이렇게 되면 안된다라는 의미가 됩니다. 이는 구현시에 참고해야 할 내용이 됩니다.





자 이제 다시 Gradient descent algorithm을 봅니다.

아래 수식을 잠깐 보면 한점에 도달할때까지 이 식을 반복된다고 합니다. 그리고 마이너스 알파(learning rate)과 J를 미분하는 식(derivative:편미분), 그리고 파라메터인 세타zero와 세타one이 동시에 업데이트가 되어야 한다고 되어있습니다. 간단히 나타내기 위해서 세타one만 조금더 살펴봅니다.




만약에 세타one 파라미터의 값이 최저점보다 크다(오른쪽에 위치)라고 생각해보면 아래 그림의 위쪽 그래프와 같이 됩니다. 이때 J함수를 미분을 하면 빨간선과 같은 기울기가 됩니다. 미분은 기울기 맞죠?

경사도를 따라 내려가는 알고리즘이니까 기울기를 따라 왼쪽으로 이동하게 됩니다. 이때 알파 뒷부분의 공식은 positive number, 플러스 수가 되는데 앞에 마이너스가 붙어 있으니까 theta값이 줄어듭니다.


이번에는 세타one 파라미터의 값이 최저점보다 작다(왼쪽에 위치)라고 생각해봅니다. 아래 그림의 아래쪽 그래프가 보이시죠. 미분한 기울기는 반대 방향의 마이너스로 생기게 됩니다. 역시 경사면을 따라서 내려오면 오른쪽으로 이동하게 되겠네요. 이때 알파 뒷부분의 공식은 negative number가 됩니다. 앞에 마이너스가 있으니 플러스 값이 되어 더해지겠네요. 그래서 오른쪽으로 이동하게 됩니다.


결국 어느 점에서 시작하더라도 최저점을 향해서 잘 찾아 움직이는 것 같습니다. 이것이 미분으로 생긴 공식이 하는 역활입니다.




이번에는 알파에 대해서 알아보겠습니다.

경사면을 내려오는 step이라고 했었는데 너무 작으면 아래 그림의 위쪽 그래프와 같이 총총걸음으로 하염없이 오래 내려옵니다. 반대로 너무 크면 아래쪽 그래프와 같이 최저점을 찾지 못하고 양쪽을 오락가락 하다가 스탭이 꼬여서 거꾸로 올라가 버리는 경우도 발생한다고 합니다. 우리가 원하는 것은 한점으로 이동하는 것(converge)인데 반대로 분산되는 것(diverge)처럼 됩니다.




만약 아래 그림과 같은 함수가 있을때 세타one에서 시작을 한다고 생각을 해보면 (파라미터가 하나이고 세타one의 위치가 곧 local optima 위치가 동일합니다) 어떤일이 발생할까요? 한번 생각해보시겠습니까? 원 강의에서 나오는 문제입니다^^




이번에는 알파에 대해서 좀더 알아보겠습니다.

알파는 learning rate이고 step인데 만약에 이 알파 값이 고정되었다면 어떻게 될까요

알파 값은 뒤에 미분으로 나타나는 식과의 곱하기입니다. 미분 값, 즉 경사도가 가파를 수록 크고 경사도가 작아질 수록 작아지게 될 것입니다. 곱하기를 하니 알파 값이 고정이라도 움직임이 점차 내려오면서 같이 작아질 것 같습니다. 아래 그래프의 표시처럼 말입니다. 별도로 알파 값을 조절하지 않아도 이 식에서 자연스럽게 적절한 값으로 조절이 되니 신통방통합니다. 멋진 알고리즘인 것 같습니다






이제 거의 다왔습니다. 배운것을 정리를 하면서 중요한 점 하나만 보면 끝이납니다.

Linear regression에서 h 함수를 만들었고, J함수를 봤습니다. 이 J 함수를 우리가 원하는 minimizing 하기 위한 알고리즘이 지금 공부하는 Gradient descent algorithm이 되겠습니다. 





이 알고리즘의 미분식에 대해서 조금 더 보면,

두개의 파라미터로 구성이 되어 있고 이것을 각각의 파라미터로 편미분을 하면 아래와 같이 두개의 식이 만들어집니다. 일단 h 함수를 대입해서 일차방정식을 넣고 이것을 처음 세타zero로 편미분을 한 것이 아래 위쪽 식이 되고 다음 세타one으로 편미분을 하면 맨밑에 식이 됩니다. 


편미분을 하게 되면 제곱은 곱하기로 내려오고 2 * 1/2m이 되어 결국 1/m이 된 것입니다. 그리고 세타zero는 원래 상수 였기때문에 x 변수가(input data) 사라지는 것이고 세타one으로 미분한 것은 x 변수가 살아있는 것이 두 식의 차이점입니다.





어찌되었든간에, 결국 두개의 파라미터 세타zero와 세타one은 동시에 업데이트 되어 경사면을 내려오게 만든다는 것이고 위에서 본것처럼 아래와 같은 굴곡있는 함수의 경우 다른 점(local optima)로 내려가는 이상한 현상이 생길 수 있다는 것입니다.




그래서 우리는 아래와 같이 하나의 최저점을 가지고 있는 활 같은 모양(bow shaped function)을 선호하며 위의 굴곡있는 함수가 만약 있다면 아래와 같은 이쁘게 구부러진 모양의 함수로 만들어야 한다는 것이 핵심입니다. 그래야 우리가 원하는 global optimum를 찾을 수 있고 이것을 잘 찾는 알고리즘이 좋은 알고리즘이 됩니다. 잘 찾았다면 결과도 아주 잘 예측할 수 있는 것이기도 하게 되겠습니다.




이제 등고선으로 표현을 해보면 아래와 같습니다. 한번 본적이 있었져?

오른쪽 동고선에 빨간점에서 시작을 합니다. 조금씩 움직이면서 이때의 파라미터로 구성이 되는 h 함수를 그리면 왼쪽의 직선처럼 되는데 실제 데이터와 조금 다르기 때문에 Cost가 아직 큽니다.




이렇게 계속 동시에 파라미터가 변경이 되면서 등고선의 중앙(global optimum)에 다다르게 되면 이때의 파라미터가 구성하는 h 함수 일차방정식인 직선을 그려보면 아래와 같이 되고 이것은 실제 결과 값과 거의 비슷하므로 우리가 찾는 것이 됩니다. 잘 찾았다는 것은 잘 학습을 했다는 것이 되겠습니다.




이와 같이 반복적으로 움직이고 판단하고 다시 움직이는 알고리즘들을 batch라고 불른다고 합니다. 뭔가 조금 어색해 보이지만 그렇게 많이 쓴다고 하니 용어만 알아두면 되겠습니다. 그럼 batch가 아닌것도 있을까? 네 있다고 합니다. 나중에 다루는 것 같습니다만 위의 편미분을 한번에 수학적으로 풀수 있다면 여러 step을 반복하지 않아도 될 것인데 이러한 것은 일부 작은 dataset에서만 가능하다고 합니다.


우리가 하려고 하는 큰 스케일의 dataset에서는 지금 배운 Gradient descent algorithm이 보다 범용적으로 사용이 가능한 좋은 알고리즘이 되겠습니다.




여러분은 Gradient descent algorithm에 대해서 모든 것을 배우셨습니다.^^

긴 글 읽으시느냐고 수고하셨습니다

우리는 Supervised 방식을 공부하고 있기 때문에 결과 값을 비교할 수 있습니다.

왜냐하면 실제 정확한 결과 값을 알고 있기 때문입니다.

이 결과 값을 비교할 수 있는 표현이 Cost입니다. 그리고 Cost를 수학적인 함수로 표현하는 것도 배우게 될 것입니다.


이전 내용에서 이어서

h 함수를 일차방정식으로 표현할 수 있었습니다. ( h = Ax + B)

여기서 A와 B를 Parameters라고 합니다. 이 파라미터가 결정이 되면 우리는 원하는 결과 값을 찾을 수 있게 됩니다.


그럼 이 파라미터 값은 어떻게 찾을 수 있을까요?

바로 minimize를 해서 찾을 수 있습니다. 

우리는 이미 결과 값을 알고 있기 때문에 실제 결과 값과 알고리즘이 수행하여 예측한 결과 값을 비교해서 그 차이를 구할 수 있는데, 이 차이가 가장 작은 즉, 실제 값과 가장 가까운 결과가 나올 수 있는 파라미터를 구하면 될 것입니다.

그러한 파라미터로 구성된 직선이 우리가 찾고자 하는 기준이 됩니다.




Dataset에서 첫번째 데이터를 보면 집의 사이즈가 2104피트인 집이 실제 가격이 460,000달러였습니다.

x가 2104 값일때 실제 결과인 h가 460,000 값이 되어야 하는 것이지요

그런데 알고리즘을 수행하여 머신이 학습한 결과 값이 400,000달러라고 가정을 해보면 실졔 값과의 차이가 60,000달러 만큼 발생하는 것을 알 수 있습니다. 이 60,000달러가 Cost로 표현이 됩니다.


Cost는 예측된 결과 값(h) - 실제 결과 값(y)으로 정의를 할 수 있는데 이 값이 마이너스(-)의 값을 가질 수 있으므로 제곱을 해줍니다. 수식으로 표현하면 Cost = (h - y)^2이 되고 아래 그림의 오른쪽 위에 표현식과 비슷하게 됩니다


첫번째 데이터에 대한 것만 보고 표현한 것이니 이것을 모든 Dataset으로 확장해서 표현을 하면 1번째 데이터부터 m번째 데이터까지의 합으로 나타낼 수 있습니다. 또 이 값을 2m으로 나누어주면 평균 값이 됩니다.


이것을 수식으로 아래 그림과 같이 표현 할 수 있습니다. 그리고 이것이 Cost 함수가 됩니다.

우리는 이 cost가 가장 적은 것을 찾아야 하는것이 목표입니다.

목표를 달성하기만 하면 우리는 정확한 값을 에측할 수 있게 되기 때문입니다




Cost 함수를 제이(J)로 표현하였고 이 J함수가 minimize 된 값을 찾는 것이 우리의 목표라고 아래 왼쪽 그림에서 표현이 되어 있습니다.





지금까지 Cost에 대해서 알아보았는데 이제부터는 이 Cost함수가 어떤 의미와 특징을 가지고 있는지 알아봅니다.


Cost함수를 좀더 간단하게 표현하기 위해서 세타zero를 0이라로 가정하여 없앴습니다. ( y = Ax 가 됩니다)

h = Ax를 그래프로 그리면 아래 왼쪽의 그림과 같이 표현이 됩니다.

여기서 또 A = 1 이라고 가정을 하면 h = x가 되니 (1,1), (2,2)의 값을 갖는 직선이 되겠지요. 

실제 결과인 y와 h의 값이 동일하다면 이때 cost 함수를 아래와 같이 풀어보면 값이 0이 됩니다.

다시말하면, A=1이고 B=0일때 Cost=0이 되는 것입니다.




이렇게 하나씩 그래프로 찍어서 보면 아래 오른쪽 그림과 같이 Cost 함수는 이차방정식의 그래프로 나타나는 것을 알 수 있습니다. 이때 minimize 된 값을 찾는 것이 목표이기 때문에 그래프에서 가장 아래쪽인 j=0이 되는 cost가 0이 되는 세타one (혹은 A)를 찾아내는 것이 목표이자 머선이 학습으로 수행하여 찾아야할 파라미터 값이 됩니다. ( A=1 )





이 J 함수를 3차원으로 나타내면 아래 그림과 같이 된다고 합니다. 이쁩니다.




위 3차원 그래프를 등고선의 형태로 표현하면 아래와 같이 된다고 합니다.

만약 왼쪽의 직선과 같은 h를 발견했다면 실제 데이터(점들)과 많이 다르기 때문에 비용함수인 J가 중앙에서 멀리 있는 것(등고선의 바깥쪽에)을 볼 수 있습니다.




그러나 이것은 우리의 목표와 맞지 않으므로 답이 아니지요

아래 그림과 같은 직선으로 표현되는 h를 발견했다면 실졔 데이터와 비슷하기 때문에 비용함수인 J가 중앙에 있는 것을 보실 수 있습니다. 우리가 찾는 minimize라는 의미는 등고선으로 표현 했을때 정중앙에 위치하는 즉, Cost가 0에 가까운 것을 찾는 다는 뜻입니다. 또 Cost가 0에 가깝다는 의미는 실제 데이터의 결과값과의 차이가 거의 나지 않는 다는 똣이고 이는 예측 가능한 정확도가 높다는 것이 됩니다.




이런 과정으로 머신이 학습을 하여 결과를 찾는 것입니다.

많은 수식과 그래프로 표현이 되었지만 요약하자면 알고리즘(머신)이 수행되면서 예측한 값과 실제 값을 비교해서 Cost를 분석하고 이 Cost가 가장 적은 기준을 찾아내는 것입니다.


이제 한걸음 들어가게 됩니다.

앞에서 공부했던 Supervised Learning에서 regression 에 대한 예시를 가지고 이것을 수학적인 표현식으로는 어떻게 표현이 되는지를 보겠습니다.


집의 사이즈에 따라서 집의 매매가격의 변화하는 데이터를 그래프로 표현하면 아래와 같습니다.

사이즈가 커지면 가격이 높아지니 선을 하나 그어볼 수 있을 것입니다.

이 직선은 사이즈와 가격에 대한 변화를 아주 잘 나타내는 그래프이자 수학적으로는 일차방정식으로 표현이 됩니다.






데이터셋의 실제 데이터들을 하나씩 열어보면 아래와 같이 사이즈와 가격으로 구성이 된 정보들을 볼 수 있습니다.

저기 지역에서는 사이즈가 2104 피트인 집이 460,000달러인가 봅니다.


DataSet의 크기, 즉 데이터의 수량을 m으로 표현을 하고

집의 사이즈를 x로 표현을 하고

집의 가격을 y로 표현하기로 했습니다.


그래서 첫번째 데이터인 x1이 2104를 표현하게 되고, y1는 460달러를 표현하게 되었습니다.

쉽게 우리가 가장 잘 아는 일차방정식과 동일합니다. ( y = Ax + B )


이 직선이 무엇이였죠? 사이즈에 따른 집의 가격들이였습니다. 이 직선을 알면 우리는 무엇을 할 수 있게 되는걸까요? 사이즈만 알면 집값을 예측할 수 있게 될 것입니다. 

그러면 우리가 알고자 하는 것은 저 직선을 만드는 것일까요? 네 맞습니다. 그런데 이것을 우리가 찾는게 아니라 알고리즘(머신)이 학습해서 찾아줄 것입니다.





개념을 도식화해서 보면 아래 왼쪽의 그림과 같이 dataset이 알고리즘을 통해서 수행이 되는데 h라고 표현이 되어 있는 Hypothesis(가설)을 세우기만 하면 x라는 입력값에서 y라는 우리가 원하는 집값을 예측하는 결과 값이 도출되게 될 것입니다.


여기서 h가 그 직선의 함수가 되고

h = Ax + B인데 아래 교수님은 조금 유식하게 세타(θ)로 표현하셨습니다. 오른쪽 녹색 보이시죠?

세타 zero가 B가 되고 세타 one이 A와 동일합니다.




이번 예제에서는 직선 형태의 regression이라 이를 Linear regression이라고 호칭합니다.

그리고 x라는 입력값(feature)이 하나이기 때문에 one variable 혹은 Univariable이라고 합니다.

이를 합치면 Univariate linear regression 이라고 하고 우리가 배운 것을 표현하는 멋진 용어가 됩니다.


머신이 학습을 하는 방식은 Supervised Learning과 Unsupervised Learning의 2가지로 구분이 됩니다.

이는 기초 데이터인 Dataset의 성격과 원하는 결과 값의 성격에 따라 다르게 사용이 됩니다.


Supervised Learning


변역하면 지도식 학습 방법입니다.

선생님이 학생을 교육하듯이 이미 답을 알고 있는 상태에서 학습을 하는 경우입니다.

DataSet이 이미 결과 값을 포함하고 있어 머신이 학습을 수행하여 나온 결과 값이 얼마정도의 오차를 가지고 있는지 알수 있는 경우에 사용될 수 있습니다.


예를들어, 집의 사이즈에 따른 집의 가격을 분석한다면 우리는 이미 평수에 따른 가격이 어떻게 구성이 되는지를 알고 있습니다. 실제로 집이 거래된 가격도 정확하게 알 수 있습니다. 이 집의 사이즈 데이터를 머신이 학습하고 수행한 결과 값은 집의 매매가로 나타나게 될 것이고 이를 실제 값과 비교해서 Cost(오차값)를 비교할 수 있습니다.


집은 사이즈가 커질 수록 매매가가 높아지기 때문에 연속적인 값으로 나타나게 됩니다. 이렇게 연속적인 결과 값으로 나오는 것을 Regression이라고 합니다. 




또는 집의 구조에 따라서 아파트인지 빌라인지 단독주택인지 구분이 되는데 이러한 값을 나타내는 것은 Classification이라고 합니다.


아래 그림은 강의에서 사용한 종양 크기에 대한 암환자 정보를 구분하는 내용입니다. 일정한 사이즈 이하인지 이상인지에 따라 악성종양인지 여부를 구분합니다. 이처럼 구분하여 나타내지는 값에 대한 분석을 Classification으로 처리하면 되는것입니다




어떠한 데이터들을 구분을 한다는 것은 어떤 기준이 필요하게 됩니다.

아래와 같은 데이터들은 선형의 기준선으로 인해 분류가 될 수 있습니다.

이렇게 잘 구분할 수 있는 선을 찾고 하는 것이 supervised에서 머신이 학습을 하여 찾아내는 결과가 됩니다.





두가지의 학습 방식은 다른 성향의 결과 값을 예측하고자 할 때 사용이 되므로 이 차이를 잘 이해해야 합니다.

머신러닝을 이용하여 무엇인가를 예측하고자 할때 적절하게 사용해야 하기 때문입니다.



Unsupervised Learning


자율학습이라고 표현되는 학습 방법입니다.

이것이 supervised와 다른 점은 우리가 답을 알고 있지 않는 상태에서 학습을 하는 경우라는 것입니다.

DataSet에 어떤 정보들이 있는지 우리는 알지 못하고 어떤 데이터로 구성이 되어 있는지도 알지 못할때 사용됩니다. 우리가 원하는 결과들은 비슷한 의미를 가진 데이터들이나 비슷한 주제로 구성된 데이터들을 분류하여 보고자 할 때 사용됩니다. 이를 clustering 혹은 grouping 이라고 표현됩니다.


예를들어, 우리의 물건을 구매한 고객 데이터를 분석한다고 생각해보면 됩니다. 연령대 별로 혹은 소비자의 소득수준으로 구분되어 판매량을 분석할 수 있을 것이고 전체 시장에서 우리 물건에 대한 시장 점유율과 같은 결과로 나타날 수도 있을 것입니다.


또는 비슷한 뉴스나 피드들을 grouping하여 사용자에게 보여주는 서비스도 가능할 것입니다. 같은 주제에 대한 다양한 정보들을 한눈에 볼 수 있어 편리할 겁니다.






또, 음성인식에서도 유용하게 활용이 될 수 있습니다.

사용자가 클럽같이 시끄러운 곳에서 오더를 할때 머신은 주위 사람들의 소리와 음악소리 같은 잡음들은 다 무시하고 사용자가 말하는 음성만 정확하게 인식이 되도록 할 수 있습니다.


아래와 같이 강의에서 분리된 음성을 직접 들려주시면서 이런 알고리즘을 실제 구현하면 저렇게 한줄로 표현이 될 수 있다고 이야기 하고 있습니다. 우리가 처음에 막연하게 생각 했던 것보다 쉬울 것 같지 않습니까?^^



Machine Learning


머신 러닝의 기본 방식은 크게 3가지로 구성이 됩니다.

분석하고자 하는 데이터를 기초로 머신이 학습 또는 task를 수행하게 되고 그 수행결과 값이 실제 값과 같은지를 판단하는 과정으로 진행이 됩니다.


여기에서 사용되는 기초 데이터를 Dataset 이라고 하며 데이터는 수량이 많고 다양할 수록 좋은 데이터가 될 것입니다. 이러한 데이터를 수집하는 단계가 있을 것입니다.


그리고 머신이 학습을 수행하는 단계에서 앞으로 공부하게 될 Algorithm 들이 적용이 될 것입니다.


이렇게 수행한 결과 값이 우리가 원하는 값이 되어야 하며, 실제 우리가 원하는 값과 비교를 하여 그 결과가 적절한 것인지 아닌지 여부를 측정하게 됩니다. 만약 원하는 값이 아니라면 수행을 계속 진행하거나 알고리즘의 수정이 필요합니다. 이렇게 수행한 결과 값과 우리가 실제로 기대하는 결과 값의 차이를 Cost로 표현하고 수학적인 함수로 표현이 될 것입니다.



History


머신 러닝에서 하나의 분야인 딥러닝은 인간의 뇌신경계를 연구하면서 발견된 내용들을 토대로 하고 있습니다.

사람의 뇌 구성을 그대로 알고리즘으로 구현했다고 봐도 될 것 같습니다.

뇌 구성은 알아도 뇌가 어떻게 동작해서 생각하고 결정을 하는지까지는 아직 알수 없을 것인데 이러한 신기한 것이 머신에서도 가능한 것이 아닌가 싶습니다. 구성만 되면 원하는 결과가 사람이 수행한 결과보다도 높은 정확도로 나타나고 있으니까 말입니다. 이미 사람보다 똑똑한 머신들이 태어났다고 봐야 할 것입니다.


약 50년전부터 인공지능에 대한 연구가 시작되어 지금까지 많은 전문가들이 발전시켜온 분야라고 하는데 우리는 강의를 통해서 한 두달만에 이런 지식을 배울 수 있다니 그저 놀랍니다.


이미 많은 분야에서 적용이 되어 서비스가 되고 있는데 대표적인 것이 검색엔진, 추천서비스, 음성인식, 얼굴인식, 자율운행 자동차등 입니다. 이러한 변화들을 보면 기존의 플레폼 성격적인 서비스(우리가 이런 서비스를 만들었으니 이렇게 사용해주세요 하는 서비스들)는 지나가고 앞으로는 사용자 개개인의 성향에 맞추어 주는 서비스(사용자마다 성향에 따라 다른 결과를 보여주는 서비스들)들이 발전될 것 같습니다.


상세한 히스토리는 김성훈 교수님의 강좌에서 '딥러닝의 기본개념' 내용을 보시면 재미있게 역사적인 스토리들을 알 수 있습니다. 교수님 좋은 강좌 항상 감사합니다. 시즌2도 기대하고 있겠습니다.^^

https://hunkim.github.io/ml/


http://daeson.tistory.com/entry/%EB%A8%B8%EC%8B%A0-%EB%9F%AC%EB%8B%9D%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC


머신러닝 분야에 세계적인 권위를 가지고 계신 Andrew Ng 교수님의 무료강좌를 공부하면서 정리를 해보려고 합니다.

https://www.coursera.org/learn/machine-learning/lecture/RKFpn/welcome

 

초기 몇개의 강의는 한글로 된 transcirpt이 지원이 되고 있습니다. 조금 지나면 모든 강의를 한글 스크릡트로 볼수 있게 될 것 같습니다.

 

아래는 소개글인데 너무 멋지고 별도로 요약정리할 필요도 없을 것 같아서 그냥 퍼왔습니다.

한번씩 읽어만 봐도 왜 우리가 머신러닝을 배워야 하는지 자연스럽게 이해할 수 있게 됩니다.

앞으로는 모든 분야에서 사용하지 않으면 안되는 기술이 될 것 같습니다.

 

 

 

기계학습 무료 온라인 강의에 오신 것을 환영합니다. 기계학습은 최근 기술 중에서 가장 흥미있는 분야중 하나인데요. 이 강의에서 여러분은 실전 연습을 통하여 현재 사용되고 있는 알고리즘을 직접 배치해보는 것을 배우게 될 것입니다. 여러분들은 자기도 모르게 학습알고리즘을 하루에도 수 십번 사용 하고 있습니다. 매일 여러분들은 인터넷 검색을 할 때 구글이나 Bing같은 곳에서 웹 검색 엔진들을 사용할텐데요, 검색엔진들이 검색을 잘 하기 위해서 학습 알고리즘이 사용됩니다. 또 이 알고리즘을 사용하여 구글이나 마이크로소프트에서 웹페이지들을 랭크 하게 됩니다. 여러분들이 페이스북이나 애플의 사진 어플리케이션을 사용 할 때 여러분과 친구들의 사진들을 인식하게 되는데 이것 또한 기계학습입니다. 이메일을 사용 할 때 이메일 스팸필터가 수많은 양의 스팸메일로부터 스팸메일을 걸러 주게 될 텐데요. 이것 또한 학습알고리즘을 사용한 것입니다. 아직 멀었지만, 여러분이나 저와 같은 지능을 가진 기계를 만들기위해서 수많은 인공지능 연구자들의 최선의 목표는 학습 알고리즘을 인간의 뇌를 흉내내서 만들어 인간의 뇌와 비슷하게 학습하게 만드는 것입니다. 이 부분에 대해서는 나중에 더 말씀 드리도록 하겠습니다. 이번 강의에서는 최신의 기계학습 알고리즘에 대하여 배워 보겠습니다. 하지만 단지 어떤 알고리즘이 사용되는지 설명하고 그 알고리즘이 어떻게 유도되는지 수학적으로는 알 필요 없으니 걱정하지마세요. 그럼 우리는 이제 이러한 알고리즘들을 사용하여 예제들을 풀어보고 어떻게 작동되는지 확인하는데 많은 시간을 보내게 될 것입니다. 그럼 왜 기계학습이 오늘날에 사용되고 있는 것 일까요? 기계학습은 인공지능분야에서 발전하여 파생되어 나갔습니다. 우리는 기계가 지능을 가지길 원했고 몇몇 간단한 일들을 스스로 해내길 원했습니다. 가령 A에서 B로갈 때 어디로 가는 게 더 빨리 갈 수 있느냐 하는 것들 말입니다. 하지만 웹검색, 사진태그, 스팸메일필터 말고도 인공지능 프로그램들이 할 수 있는 우리가 모르는 더 많은 부분들이 있습니다 우리가 여기서 알 수 있는 한 가지는 기계가 스스로 학습한다는 사실입니다. 그래서 기계학습은 컴퓨터의 새로운 능력을 불어넣어 향상 시켜주기 때문에 오늘날 기초과학과 산업의 여러 분야에서 사용되고 있습니다. 제가 기계학습분야에서 있는 동안 헬리콥터조종사, 생물학자, 컴퓨터시스템 종사자들 (이곳 스탠포드 학생들)과 얘기하며 그리고 최근에 학습알고리즘을 그들의 시스템에 적용하고 싶어 하는 실리콘밸리회사들로부터 2,3주에 한번 이메일을 받고 있습니다. 이 같은 현상은 기계학습이 필요한 분야가 점차 확산 되고 있다는 뜻이기도 합니다. 자동화로보틱스, 생물학계산, 실리콘밸리의 수많은 일 등.. 이것들은 기계학습의 강력한 이점을 이용하고자 합니다. 여기 기계학습의 간단한 예가 있습니다. 데이터베이스 수집입니다. 기계학습이 발전하게 된 이유 중 하나는 웹과 모든 것이 자동화가 되었기 때문인데요. 이것은 전보다 우리가 가지고 있는 데이터가 훨씬 많아 졌기 때문입니다. 예를 들어, 실리콘밸리의 수 많은 회사들이 웹에서 클릭된 데이터를 수집하려고 합니다. 이것을 클릭스트림데이터라고 하는데 기계학습 알고리즘을 사용하여 이 데이터들을 수집하고 사용자가 어떠한 서버가 더욱 쾌적한지 알아내고 유저에게 더 나은 서비스를 제공할 수 있게 됩니다. 이것은 현재 실리콘밸리에서 여러 핵심분야 중 하나입니다. 의료 기록. 자동화가 되면서 우리는 전자 의료기록부를 가지게 되었습니다. 의료 기록들의 분석을 통하여 병이 낫게 하는데 도움이 되게 되었습니다. 또, 생물학 계산 자동화를 통하여 생물학자들은 엄청난 양의 유전자를 분석할 수 있게 되었고 기계학습알고리즘이 인간 게놈을 이해하는데 도움을 주게 되었습니다. 공학분야 역시 마찬가지로 점점 더 커져가는 데이터를 처리해야하는 상황이 왔습니다. 그래서 현재 그 방대한 데이터들을 학습알고리즘을 사용하여 분석하고 있습니다. 다음으로 수동적으로 프로그래밍을 할 수 없을 때 사용하는 자동화 학습 프로그래밍분야입니다. 예를들면, 저는 자동화 헬리콥터를 수년간 연구 했습니다. 처음에 저는 헬리콥터가 비행하게 만드는 컴퓨터 프로그래밍 법을 몰랐습니다. 연구 끝에 알아낸 한가지 방법은 컴퓨터가 스스로 학습하여 헬리콥터가 날게 하는 방법이었습니다.


이것은 또한 미국에서 해외로 우편물을 발송할 때 비용이 많이 들지 않게 하는 방법으로도 쓰이고 있습니다. 편지봉투에 이렇게 써놓으면 학습알고리즘이 손글씨를 분석하여 자동으로 분류를 하게 됩니다. 이같은 기술을 통하여 불과 몇센트 만으로 수천마일의 거리로 우편을 보낼 수 있게 합니다. 그리고 자연언어처리기법이나 컴퓨터비전분야를 본 적이 있으실 겁니다. 이것 들은 언어를 이해하고 그림들을 식별하는 인공지능 분야입니다. 수많은 자연언어 처리기법과 컴퓨터비전 분야는 오늘날 기계학습에 적용 되고 있습니다. 또한 스스로 프로그래밍을 할 수 있는 학습알고리즘은 널리 이용되고 있습니다. 여러분들은 자주 아마존이나 넷플릭스 또는 아이튠즈 지니어스를 이용 보셨을 겁니다. 그곳에서 영화나 제품, 음악들을 추천하는 서비스를 하고 있습니다. 이것도 학습알고리즘을 이용한 것입니다. 만약 사용자가 수십만이라고 생각해 보세요, 수십만의 사용자를 다루는데 매번 다른 프로그래밍을 할 수는 없을 것입니다. 이것들을 할 수 있는 방법은 오직 기계가 스스로 추천을 할 수 있게끔 만드는 것입니다. 여러분의 취향을 고려해서요. 마지막으로 학습알고리즘은 오늘날 인간이 학습하는 것과 인간의 두뇌를 이해하기 위하여 사용 되고도 있습니다. 앞으로 연구자들이 어떠한 과정으로 인공지능의 꿈을 어떻게 이뤄나가고 있는지 얘기 할 것입니다. 몇 달 전에 한 학생이 상위 12개의 IT기술들이 나온 기사를 보여줬습니다. 그 기술들은 IT기술 분야의 전문가들이 부인 할 수 없는 유망한 기술들 이었습니다. 약간 예전의 기사임에도, 그 상위 12개의 기술들 중 가장 전망 있는 IT기술은 바로 기계학습분야 였습니다. 이곳 스탠포드에서도, 매년 수많은 채용인들이 기계학습분야를 전공한 학생들을 채용하기 위한 수요가 매년 증가 하고 있습니다. 그래서 저는 이 기술의 수요가 매우 급격하게 증가하고 있으며 기계학습을 배우는 것은 매우 가치 있는 시간이 될 것이라 생각합니다. 다음 강의에서 우리는 기계학습이 무엇인가에 대하여 좀 더 보편적인 정의를 알려 드리겠습니다. 그리고 기계학습 문제의 종류들과 알고리즘에 대하여 얘기 해보겠습니다. 여러분은 주요 기계학습기술들을 선택 하고 여러 알고리즘 중 하나를 어떻게 선택해야하는지, 언제 그 알고리즘을 적절하게 사용 할 것인지에 대하여 배워봅시다.

Apache Ambari는 손쉬운 웹 UI 및 REST API 사용을 제공하여 Hadoop 클러스터의 관리 및 모니터링을 간소화합니다. Ambari는 Linux 기반 HDInsight 클러스터에 포함되어 있으며 클러스터를 모니터링하고 구성을 변경하는데 사용됩니다.


ubuntu 14 기준으로 설치하는 방법은 다음과 같습니다.


$ cd /etc/apt/sources.list.d

$ sudo wget http://public-repo-1.hortonworks.com/ambari/ubuntu14/2.x/updates/2.2.2.0/ambari.list

$ sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com B9733A7A07513CAD

$ sudo apt-get update

$ sudo apt-get install ambari-server


$ sudo ambari-server setup

# 설정 변경은 안하는걸로 하는게 속 편합니다.


$ sudo ambari-server start


# 로그 확인

cat /var/log/ambari-server/ambari-server.out


웹 접속

http://<ambari-server-host>:8080.

admin/admin


그런데, 기존에서 구성되어 있는 hadoop과 spark의 cluster를 import 할수는 없는것 같습니다.

아마도 Ambari에서 사용하는 HDP로 새로운 cluster 구성을 생성해야 하는 모양입니다.



참조

https://cwiki.apache.org/confluence/display/AMBARI/Install+Ambari+2.1.2+from+Public+Repositories

지금까지 총 4대의 분산 환경 서버에 기본환경을 설정하고 Hadoop을 설치해보았습니다.

이번에는 MapReduce보다 빠른 속도에 분산환경을 지원하는 메모리 기반의 Spark를 설치하고 테스트를 해보겠습니다.



Spark 설치하기



1. Spark 버젼 확인


아래 사이트에 접속하여 설치하고자 하는 spark의 버젼을 확인합니다.

http://spark.apache.org/downloads.html



2. Spark 2.0.2 설치


# home으로 이동

$ cd ~


# 설치파일 다운로드

$ wget http://www.eu.apache.org/dist/spark/spark-2.0.2/spark-2.0.2-bin-hadoop2.7.tgz


# 압축 해제

$ tar -zxf spark-2.0.2-bin-hadoop2.7.tgz


# 디렉토리명 변경

$ mv spark-2.0.2-bin-hadoop2.7/ spark


# 환경 변수 설정

$ vi .bashrc

----------------------------------------------------------------------------------

export YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop

export SPARK_HOME=/home/hduser/spark

export PATH=$PATH:$SPARK_HOME/bin



3. Spark on YARN


yarn 위에서 Spark를 실행할 수 있습니다. 샘플 예제를 한번 실행해보도록 합니다.

cluster 모드는 다른 node에서 driver를 실행시키는 방식이고, client 모드는 자신의 node에서 driver를 실행시키는 방식이니 상황에 따라서 적절하게 사용하면 되겠습니다.


$ spark-submit --class org.apache.spark.examples.SparkPi \

    --master yarn \

    --deploy-mode cluster \

    --driver-memory 4g \

    --executor-memory 2g \

    --executor-cores 1 \

    ~/spark/examples/jars/spark-examples*.jar \

    10


$ spark-submit --class org.apache.spark.examples.SparkPi \

--master yarn \

--deploy-mode client \

    --driver-memory 4g \

    --executor-memory 2g \

    --executor-cores 1 \

    ~/spark/examples/jars/spark-examples*.jar \

10   



4. Spark in Standalone


Spark는 독립적인 모드로도 설치 및 수행이 가능합니다. 


### yarn에서 돌리려면 master에만 설치하면되지만, Standalone mode를 위해서는 모든 slave에 설치/배포

$ scp -r /home/hduser/spark ubuntu1:/home/hduser/spark

$ scp -r /home/hduser/spark ubuntu2:/home/hduser/spark

$ scp -r /home/hduser/spark ubuntu3:/home/hduser/spark


### master 서버에서만 이후 진행

### slave 서버들을 등록

$ vi ~/spark/conf/slaves

----------------------------------------------------------------------------------

ubuntu1

ubuntu2

ubuntu3


### 환경 설정

$ vi ~/spark/conf/spark-env.sh

----------------------------------------------------------------------------------

SPARK_WORKER_MEMORY=2g


### 서비스 시작/종료

$ ~/spark/sbin/start-all.sh

$ ~/spark/sbin/stop-all.sh


### web ui for spark

http://ubuntu0:8080


### 테스트

$ spark-submit \

     --master spark://ubuntu0:7077 \

     --class org.apache.spark.examples.SparkPi \

     ~/spark/examples/jars/spark-examples*.jar \

     100



예제가 잘 수행이 되면 정상적으로 설치 및 설정이 된것입니다.

web ui에서 해당 application들이 수행되는 모습을 모니터링 할 수 있으며, 결과와 로그도 볼 수 있습니다.


다음에는 간단한 튜토리얼 예제 프로그램을 통해서 분산처리 프로그래밍을 살펴보도록 하겠습니다.

길고 긴 설치과정을 따라 하시는냐 수고가 많으셨습니다.



5. Spark history server


Spark에서 제공하는 history server를 띄워보겠습니다. 디폴트 UI port는 18080입니다.


$ hadoop fs -mkdir -p /user/hduser/spark/history


$ sudo vi ~/spark/conf/spark-defaults.conf

----------------------------------------------------------------------------------

park.master                      spark://ubuntu0:7077

spark.eventLog.enabled         true

spark.eventLog.dir               hdfs://ubuntu0:9000/user/hduser/spark/history

spark.history.fs.logDirectory    hdfs://ubuntu0:9000/user/hduser/spark/history

spark.history.provider           org.apache.spark.deploy.history.FsHistoryProvider


$ ~/spark/sbin/start-history-server.sh


이전 내용에서 각 서버들에 공통적인 기본환경들을 구성하였습니다.

이번에는 본격적으로 Hadoop을 설치하여 서비스를 기동시키고 Mapreduce 테스트까지 돌려보겠습니다.



Hadoop 설치하기


먼저 master서버인 ubuntu0 서버부터 설치를 진행을 합니다.

그리고 진행 중간부분쯤에 설치된 패키지를 나머지 서버들로 배포를 하고 각 서버별로 재수정을 하도록 하겠습니다.


1. data 디렉토리 생성


hadoop의 HDFS(파일시스템)에 사용될 디렉토리를 생성합니다.


### 모든 서버에 data 디렉토리를 생성합니다.

$ sudo mkdir /data

$ sudo chown -R hduser:hadoop /data


### master 서버에서만 namenode 디렉토리를 생성합니다.

$ mkdir /data/tmp /data/namenode


### slave 서버들에서만 datanode와 userlogs 디렉토리를 생성합니다.

$ mkdir /data/tmp /data/datanode /data/userlogs



2hadoop 2.7.1 설치


하둡 파일을 다운로드하고 설치 및 기본 path 설정을 해줍니다.


$ cd ~


### apache repository로 부터 다운로드

$ wget http://www.us.apache.org/dist/hadoop/common/hadoop-2.7.1/hadoop-2.7.1.tar.gz


## 압축 해제

$ tar -zxf hadoop-2.7.1.tar.gz


## 디렉토리 이름변경

$ mv hadoop-2.7.1 hadoop


## 유저계정에 path설정

$ vi ~/.bashrc

----------------------------------------------------------------------------------

# Java and Hadoop variables

export HADOOP_HOME=/home/hduser/hadoop

export JAVA_HOME=/opt/jdk/jdk1.8.0_111/ 

export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

export HADOOP_CLASSPATH=${JAVA_HOME}/lib/tools.jar


## 하둡 환경 설정

$ vi ~/hadoop/etc/hadoop/hadoop-env.sh

----------------------------------------------------------------------------------

export JAVA_HOME=/opt/jdk/jdk1.8.0_111/ 



3. master서버의 config 파일 설정


우선 master서버의 config 파일들이 있는 디렉토리로 이동하여 설정 xml 파일을 작성해줍니다.


$ cd ~/hadoop/etc/hadoop/



### Configuration for the Master

$ vi core-site.xml

----------------------------------------------------------------------------------

<configuration>

    <property>

        <name>fs.defaultFS</name>

        <value>hdfs://ubuntu0:9000</value>

    </property>

    <property>

        <name>hadoop.tmp.dir</name>

        <value>/data/tmp</value>

    </property>

</configuration>


### hdfs 환경 설정 (디폴트 복제는 3이지만 2만 해줍니다.)

$ vi hdfs-site.xml

----------------------------------------------------------------------------------

<configuration>

    <property>

        <name>dfs.replication</name>

        <value>2</value>

    </property>

    <property>

        <name>dfs.namenode.name.dir</name>

        <value>/data/namenode</value>

    </property>

</configuration>


### yarn 환경 설정 (memory와 core수는 각자의 서버에 적절한 값으로 설정해줍니다.)

$ vi yarn-site.xml

----------------------------------------------------------------------------------

<configuration>


    <!-- YARN master hostname -->

    <property>

        <name>yarn.resourcemanager.hostname</name>

        <value>ubuntu0</value>

    </property>


    <!-- YARN settings for lower and upper resource limits -->

    <property>

        <name>yarn.scheduler.minimum-allocation-mb</name>

        <value>512</value>

    </property>

    <property>

        <name>yarn.scheduler.maximum-allocation-mb</name>

        <value>4096</value>

    </property>

    <property>

        <name>yarn.scheduler.minimum-allocation-vcores</name>

        <value>1</value>

    </property>

    <property>

        <name>yarn.scheduler.maximum-allocation-vcores</name>

        <value>2</value>

    </property>


    <!-- Log aggregation settings -->

    <property>

        <name>yarn.log-aggregation-enable</name>

        <value>true</value>

    </property>

    <property>

        <name>yarn.log-aggregation.retain-seconds</name>

        <value>86400</value>

        <description>How long to keep aggregation logs. Used by History Server.</description>

    </property>


</configuration>


### mapreduce 환경 설정 (memory 값은 각자의 서버에 적절하게 지정해주도록 합니다.)

$ vi mapred-site.xml

----------------------------------------------------------------------------------

<configuration>


    <property>

        <name>mapreduce.framework.name</name>

        <value>yarn</value>

    </property>


    <!-- MapReduce ApplicationMaster properties -->

    <property>

        <name>yarn.app.mapreduce.am.resource.mb</name>

        <value>1536</value>

    </property>

    <property>

        <name>yarn.app.mapreduce.am.command-opts</name>

        <value>-Xmx1536m</value>

    </property>


    <!-- Mappers and Reducers settings -->

    <property>

        <name>mapreduce.map.memory.mb</name>

        <value>2048</value>

    </property>

    <property>

        <name>mapreduce.map.cpu.vcores</name>

        <value>1</value>

    </property>

    <property>

        <name>mapreduce.reduce.memory.mb</name>

        <value>4096</value>

    </property>

    <property>

        <name>mapreduce.reduce.cpu.vcores</name>

        <value>1</value>

    </property>

    <property>

        <name>mapreduce.job.reduces</name>

        <value>2</value>

    </property>


    <!-- History Server settings -->

    <property>

        <name>mapreduce.jobhistory.address</name>

        <value>ubuntu0:10020</value>

    </property>

    <property>

        <name>mapreduce.jobhistory.webapp.address</name>

        <value>ubuntu0:19888</value>

    </property>



</configuration>


### 마스터 서버에만 slave 서버들을 등록해줍니다.

$ vi slaves

----------------------------------------------------------------------------------

ubuntu1

ubuntu2

ubuntu3



4. slave 서버들로 배포


지금까지 기본 설치 및 설정한 hadoop 패키지를 다른 서버로 배포합니다.

개별적으로 설치하는 것보다 시간을 단축시킬 수 있어 편리합니다.


### 서버별 배포

$ scp -r /home/hduser/hadoop ubuntu1:/home/hduser/hadoop

$ scp -r /home/hduser/hadoop ubuntu2:/home/hduser/hadoop

$ scp -r /home/hduser/hadoop ubuntu3:/home/hduser/hadoop



5. slave 서버들의 환경 설정


### Configuration for the Slaves

### Slave1 server에서 수정하여 다른 Slave2, Slave3 server들로 동기화 전송함


$ vi core-site.xml

----------------------------------------------------------------------------------

<configuration>

    <property>

        <name>fs.defaultFS</name>

        <value>hdfs://ubuntu0:9000</value>

    </property>

    <property>

        <name>hadoop.tmp.dir</name>

        <value>/data/tmp</value>

    </property>

</configuration>



$ vi hdfs-site.xml

----------------------------------------------------------------------------------

<configuration>

    <property>

        <name>dfs.datanode.data.dir</name>

        <value>/data/datanode</value>

    </property>

</configuration>



$ vi yarn-site.xml

----------------------------------------------------------------------------------

<configuration>


    <property>

        <name>yarn.nodemanager.aux-services</name>

        <value>mapreduce_shuffle</value>

    </property>


    <!-- Link to the master node -->

    <property>

        <name>yarn.resourcemanager.hostname</name>

        <value>ubuntu0</value>

    </property>


    <!-- Available resources for YARN containers on this node -->

    <property>

        <name>yarn.nodemanager.resource.memory-mb</name>

        <value>7048</value>

    </property>

    <property>

        <name>yarn.nodemanager.resource.cpu-vcores</name>

        <value>2</value>

    </property>


    <property>

        <name>yarn.nodemanager.vmem-check-enabled</name>

        <value>false</value>

    </property>


    <!-- Log aggregation settings -->

    <property>

        <name>yarn.log-aggregation-enable</name>

        <value>true</value>

    </property>

    <property>

        <name>yarn.nodemanager.log-dirs</name>

        <value>/data/userlogs</value>

    </property>

    <property>

        <name>yarn.log.server.url</name>

        <value>ubuntu0:19888</value>

    </property>

    <property>

        <name>yarn.nodemanager.delete.debug-delay-sec</name>

        <value>86400</value>

    </property>


</configuration>


### 변경사항 동기화 전송

$ rsync -av /home/hduser/hadoop/etc/hadoop ubuntu2:/home/hduser/hadoop/etc

$ rsync -av /home/hduser/hadoop/etc/hadoop ubuntu3:/home/hduser/hadoop/etc



6. HDFS 시작


설치가 모두 완료가 되었으니 이제 hdfs (파일시스템)을 기동합니다.


### namenode를 format 하고 hdfs start.

$ hadoop namenode -format daesonyCluster

$ start-dfs.sh    #서비스 시작

$ stop-dfs.sh    #서비스 종료


### web ui에서 Namenode 1개와 Datanode 3개가 잘 나타나면 정상

http://ubuntu0:50070


### 만약 이상이 있다면 각 서버별로 로그들을 확인

$ cd ~/hadoop/logs


여기서 한가지 주의할 점이 있습니다.

초기 설치시에는 해당사항이 없지만 한번 서비스를 진행하다가 다시 namenode를 format 해야하는 일이 생기면, 반듯이 먼저 datanode 하위 모든 파일을 삭제하고 진행을 해야 합니다. 만약 하위 파일들을 삭제하지 않고 format을 하면 namenode의 clusterId와 datanode의 clusterId가 달라져서 정상적으로 동작하지 않을 수 있습니다.

참고 : http://hadooptutorial.info/incompatible-clusterids/



7. Filesystem 테스트


Hadoop 파일시스템에 디렉토리를 생성하고 테스트 파일(/opt/test.txt)을 업로딩 해봅니다.


$ hadoop fs -mkdir /user

$ hadoop fs -mkdir /user/hduser

$ hadoop fs -put /opt/test.txt /user/hduser

$ hadoop fs -ls /user/hduser



8. Yarn 시작


하둡의 분산환경에서 리소스를 관리해주는 yarn 서비스를 시작합니다.


$ start-yarn.sh    #서비스 시작

$ stop-yarn.sh    #서비스 종료


#web ui for yarn

http://ubuntu0:8088



9. history server 시작


application이 실행이 되면 그 수행 기록들이 history server에 남게 됩니다.


$ mr-jobhistory-daemon.sh start historyserver    #서비스 시작

$ mr-jobhistory-daemon.sh stop historyserver    #서비스 종료


#web ui for history

http://ubuntu0:19888



10. MapReduce 예제 실행


여기까지 잘 진행이 되었다면 설치가 모두 완료가 되었습니다.

정상적으로 동작하는지 테스트를 위해서 PI 값을 구하는 예제를 실행해봅니다.


저는 해당 예제의 실행 속도가 약 1분 30초 정도 걸리는 것을 볼 수 있습니다. 

이는 datanode의 갯수와 cpu, memory에 따라 분산처리 성능의 차이가 발생하니 결과값을 비교해 보시길 바랍니다.


$ yarn jar $HADOOP_HOME/share/hadoop/mapreduce/*examples*.jar pi 50 100

----------------------------------------------------------------------------------

Job Finished in 82.415 seconds

Estimated value of Pi is 3.14160000000000000000


# ResourceManager UI or History Server UI 에서 해당 log를 볼수있게됨

$ yarn logs --applicationId application_1482330106523_0001 > pi_app.log


만약에 실행중에 container-is-running-beyond-memory-limits 와 같은 오류가 발생을 한다면 yarn 환경설정에서 메모리 설정에 문제가 발생한 경우입니다. 각 서버별로 로그들을 확인하고 충분한 메모리를 할당해주도록 합니다.

참조 : http://stackoverflow.com/questions/21005643/container-is-running-beyond-memory-limits


수고하셨습니다~ Hadoop 설치가 모두 완료되었습니다.

MapReduce를 사용해서도 많은 것을 수행할 수 있지만, 디스크 IO 작업이 많이 발생하기에 최근에는 메모리 기반의 Spark을 많이 사용하고 있습니다. 다음에는 Spark에 대해서 알아보도록 하겠습니다.



http://daeson.tistory.com/entry/Hadoop-Cluster-Spark-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0-1%EC%84%9C%EB%B2%84-%ED%99%98%EA%B2%BD%EA%B5%AC%EC%84%B1



분산환경의 빅데이터 서버를 구성하기 위해서는 apache hadoop을 많이 사용하고 있습니다.

데이터가 점차 중요해지는 시기가 되고 있고 엄청나게 많은 데이터가 넘쳐나고 있는 지금의 세상에서 어쩌면 가장 필수적인 서버 환경이 되지 않을까 싶은 생각이 듭니다.


그래서, 올해 마지막이자, 개인적인 연말 프로젝트로 시작하는 분산컴퓨팅 환경을 구축하려고 합니다.

ubuntu 14 서버 총 4대를 가지고 hadoop cluster 환경을 구축하고 이어서 spark까지 해보도록 하겠습니다.


워낙 길고 긴 여정이 될 내용인지라 너무 길어서 조금 나눠서 올릴 계획입니다. 

아마 3~4부 정도 되지 않을까 싶으네요.




서버 환경 구성하기


일단 hadoop을 설치하기 전에,

4대의 ubuntu 서버들 모두에게 공통적으로 기본 환경 구성에 필요한 내용들을 먼저 해주어야 합니다.



1. user/usergroup 생성


모든 서버에 hadoop 사용자 그룹과 유저를 생성하고 권한을 부여해 줍니다.


### 모든 서버에 hadoop 유저그룹과 hduser 유저 생성
$ sudo addgroup hadoop
$ sudo adduser --ingroup hadoop hduser

### sudoers file에 hduser 추가
$ sudo visudo
----------------------------------------------------------------------------------

hduser ALL=(ALL:ALL) ALL

### hduser로 로그인
$ su - hduser


2. ssh 설정


hadoop은 분산처리시에 서버들간에 ssh 통신을 자동적으로 수행하게 됩니다.

이를 위해서 암호입력 없이 접속이 가능하도록 ubuntu0 서버에서 공개키를 생성하고 생성된 키를 각 서버들에 배포해줍니다.


### ssh 설정 변경

$ sudo vi /etc/ssh/sshd_config

----------------------------------------------------------------------------------

PubkeyAuthentication yes

AuthorizedKeysFile      .ssh/authorized_keys


### 공개키를 생성

$ mkdir ~/.ssh

$ chmod 700 ~/.ssh

$ ssh-keygen -t rsa -P ""

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys


### 공개키를 각 서버에 배포

$ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu1

$ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu2

$ ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu3


### 접속 테스트

$ ssh ubuntu1



3. java 설치


Hadoop이 JVM을 사용하기 때문에 모든 서버에 java SDK를 설치하도록 합니다.

현재 Hadoop 버젼이 2.7.* 이며, 버젼 2 이상부터는 java 1.7 이상에서만 지원이 되기에 이미 설치가 되어 있다면 버젼확인을 해보시길 바랍니다.


여기서는 현재 최신 버젼인 java 1.8을 설치하겠습니다.


### directory 생성
$ sudo mkdir /opt/jdk
$ cd /opt

### Download archive
$ sudo wget --header "Cookie: oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u111-b14/jdk-8u111-linux-x64.tar.gz"

### Unpack
$ sudo tar -zxf jdk-8u111-linux-x64.tar.gz -C /opt/jdk

### Update Ubuntu alternatives symbolic links
$ sudo update-alternatives --install /usr/bin/java java /opt/jdk/jdk1.8.0_111/bin/java 100
$ sudo update-alternatives --install /usr/bin/javac javac /opt/jdk/jdk1.8.0_111/bin/javac 100

$ java -version


java 버젼정보가 보여지면 정상적으로 설치가 잘 되었습니다.



4. locale 확인(옵션)


모든 서버의 locale 정보를 확인해보고 en_US.UTF-8 혹은 ko_KR.UTF-8 이 아닌 경우에만 변경을 해주면 됩니다.

일반적으로는 변경할 필요가 없으니 옵션사항으로 생각하시고 skip 하시면 되겠습니다.


### 정보 확인

$ locale
$ cat /etc/default/locale

### locale 변경하기
$ sudo locale-gen ko_KR.UTF-8
$ vi /etc/default/locale
----------------------------------------------------------------------------------
LANG="ko_KR.UTF-8"
LANGUAGE="ko_KR:ko:en_US:en"

### 변경된 locale을 적용하기 (서버 재부팅 필요없음)
$ source /etc/default/locale

### 만약 언어 설정이 제대로 적용이 되지 않으면 아래의 설치 여부를 확인해보세요
### 설치된 언어팩 리스트 확인
$ sudo apt list --installed | grep language*

### 설치 가능한 리스트 확인

$ sudo apt-cache pkgnames | grep language-pack-ko



5. hosts 파일 수정


분산 환경이기 때문에 4대의 서버 모두에 접속이 자유롭게 되어야 합니다.

이를 위해서 모든 서버들의 hosts 파일에 ip와 host 이름을 생성해 주도록 합니다.

참고로 여기서는 ubuntu0이 master 서버가 될 예정이고, 그외 서버들은 slave 서버가 될 예정입니다.


### hosts 파일 수정

$ sudo vi /etc/hosts
----------------------------------------------------------------------------------
10.1.1.58        ubuntu0
10.1.1.13       ubuntu1
10.1.1.15       ubuntu2
10.1.1.221      ubuntu3

### 확인

$ cat /etc/hosts



6. hostname 변경


각각 4대 서버들의 이름을 위에서 지정한 host 이름과 동일하게 맞춰주도록 합니다.


### ubuntu0 서버의 경우

$ sudo vi /etc/hostname

----------------------------------------------------------------------------------

ubuntu0


### 변경사항 적용하기 (서버 재부팅 필요없음)

$ sudo /bin/hostname -F /etc/hostname



여기까지 되면 기본적인 서버들의 환경설정이 모두 완료되었습니다.

다음에는 Hadoop을 설치하고 구동해보도록 하겠습니다.



빅데이터 저장소


- 1테라 바이트를 약 100MB/S 로 전송한다면 2시간 반 이상 걸린다.

- 100개의 드라이브가 있고, 각 드라이브는 100/1씩 저장하고 병렬로 동작한다면 2분내에 데이터를 읽을 수 있다

- 병렬 분산처리를 위해서는 하드웨어 장애와 데이터 분할 결합에 대한 고려가 필요하다.

- 하둡은 안정적인 공유저장소(HDFS)와 분산 프로그래밍 프레임웍(맵리듀스)을 제공한다.



HDFS


- 파일시스템(Storage)

- FILE은 Block 단위(64MB or 128MB)로 분할되고 분산되어 저장됨

- 분할된 정보는 Name node(master)에 메타정보가 기록이 되고, 실제 분할된 파일은 Data node(Slave)들에 분산되어 저장이 됨

- Name node 가 없으면 Data node에 저장된 분할된 파일을 찾을 수 없다.

- 각 Block은 장애 복구 용도로 복제본이 생성(default 3 copy) 되어 여러 Data node에 분산되어 저장이 된다.

- HDFS 접근 방법 : Shell 사용(hadoop fs), Java API, Ecosystem(Hue, Sqoop, Flume)

- A.log 파일을 hadoop fs -get 하여 가져올때 Name node에서 해당 파일의 메타 정보를 기준으로 분산저장이 되어 있는 Data node에 저장된 파일을 찾아온다. 이때, 복제본중에서 리소스가 여유있는 서버(혹은 Data node)에 저장되어 있는 파일을 찾아준다.

- Job tracker(master) 데몬이 각각의 task들을 관리해주고 있고, Task tracker(slave) 데몬은 각 Data node에 있는 분산파일 처리를 담당하고 있다.

- Task tracker는 mapper task와 reducer task로 구성이 되어 있으며 해당 task가 위치한 Data node의 데이터를 사용해서 MapReduce를 수행한다.



MapReduce


- Hadoop 클러스터의 분산 데이터를 처리하기 위한 방식(computation)

- 큰 파일을 분할(map)하여 저장하고, 분할된 파일을 다시 하나로 병합(reduce)하는 프레임웍

- 예시, wordcount(단어 갯수 세기), 1억개 단어를 가지고 있는 하나의 파일을 단일 프로세스로 수행하는 것보다 100개 단어를 가지는 100만개 파일로 분할하여 각각 수행하고 이 결과를 최종 병합하여 수행하는 개념이다.

- map은 다수의 data node에 동일한 작업을 수행한다.

- HDFS(Disk)에서 데이터를 read하여 MapReduce 수행하고 완료되면 HDFS(Disk)에 데이터를 다시 write한다.

- Disk IO는 비용이 크기 때문에 이를 Memory로 대체하는 방법이 대안으로 제시된다. (Spark)

- 각 data node의 task들이 모두 완료가 되어야 Reduce를 수행할 수 있다. (하나라도 늦게 끝나면 전체적으로 처리시간이 늦어지는 문제점이 있다.)

- Mapper는 Key/Value 형태로 데이터를 읽어서 처리하고 그 결과를 [Key/Value] List 형태로 출력한다.

- Mapper 출력의 Key 값은 중요하게 사용할 수도 있고 무시할 수도 있고 변경하여 새로운 key를 생성할 수도 있다.

- Mapper는 각 pc에서 memory를 사용해서 처리됨으로 시간이 짧게 걸린다.

- Reducer는 shuffle, sort가 이루어지고 최종적으로 원하는 결과를 출력하도록 수행이 된다.

- shuffle은 Mapper가 출력한 데이터를 Reducer에게 적절히 배분하여 전달해주어야 함으로 시간이 상당히 오래걸린다.(하둡이 해줌)

- sort는 key 값을 cache하여 같은 key 값을 갖는 데이터는 같은 reducer로 전달이 된다.

- Reducer의 입력은 Mapper의 출력인 [Key/Value] List 형태가 되고, 출력은 Key/Value 가 된다.

- Reducer의 출력은 다시 HDFS에 저장된다.

- MapReduce 프로그램은 Java or Python으로 한다.





HIVE


- MapReduce 프로그램을 통해서 데이터를 처리하거나 분석해야하는데 데이터 분석자는 프로그램을 할줄 모른다.

- 페이스북에서 이에 대한 고민을 통해서 Hive를 만들었다.

- RDBMS의 Sql와 비슷하게 작성된 문장(HiveQL)을 Hive가 이를 Mapreduce로 converting 하여 수행해준다.

- structured data 를 Hadoop file system에 저장하기 위한 data warehousing system이다.

- MapReduce를 몰라도 대용량 데이터를 처리하기 용이하다.

- high level 언어임으로 단점이 발생함.(개별 record의 insert, update, delete, transaction이 지원안됨)

- 로그 분석, Data/Text mining(기계학습), 광고배달, 스팸방지등에 활용된다.

- Local PC에 mysql DB를 생성하고 메타데이터(테이블)를 생성 한후 HDFS로 올리는 방법을 많이 사용한다. 직접 HDFS에 생성하는 것은 힘듬

- RDBMS Table을 Hadoop HDFS File로 올릴때에는 Sqoop을 사용한다.

- Hive도 Metastore(master)가 있고, Hive Tables(slave)가 있다. HDFS의 구성과 비슷하게 생성이 됨.

- 기존의 RDBMS 데이터를 HDFS에서 사용이 가능하다.

- Hive에서 ngrams를 지원해준다.

- Hive에서 sentences() 함수는 문장을 array of words로 변환해준다. 2개 이상의 문장은 2-dimensional로 변환해준다.



n-grams


- 검색엔진과 같은 application에서 검색결과의 spelling 교정에 사용

- 웹 페이지에서 가장 중요한 topics 찾는데 사용

- SNS message등에서 트랜드 topics 검색에 사용



Python Basics


http://ai.berkeley.edu/tutorial.html#PythonBasics



pySpark


- RDD(Resilient Distributed Dataset) : 메모리에 데이터 손실이 되어도 다시 생성이 가능하고, 메모리에 분산 저장되어 있고, 초기 데이터는 파일을 통해 가져온다.

- RDD는 spark의 기본적인 데이터 단위이다.

- RDD를 생성하는 방법

sc.textFile("text.txt") #from file to RDD

sc.parallelize(num) #from memory(list) to RDD

objectRDD.map(lambda line: line.upper()) #from RDD to new RDD

- RDD Operations

Actions : RDD의 값을 리턴하거나 내장함수를 사용한다.

Transformations : 현재 RDD로 부터 새로운 RDD를 생성한다.

- RDD는 immutable이여야 하며, 절대로 값이 불변이다. 그러므로 변경하고자 할때에는 transformation을 통해 새로운 RDD로 생성해야 한다.

- transformation에 사용되는 대표적인 함수는 map(f), filter(f), flatMap(f), distinct() 이다.

http://spark.apache.org/docs/latest/programming-guide.html#transformations

- action에 사용되는 대표적인 함수는 count(), take(n), collect(n), saveAsTextFile(path) 이다.

http://spark.apache.org/docs/latest/programming-guide.html#actions

- RDD 데이터는 action 함수로 인한 작업을 만날때까지는 실제적으로 수행/처리되지 않는다. transformations는 즉시 수행이 되지 않는다. (Lazy Execution)

- 복잡한 처리를 한번에 수행하게 되면 시간이 오래걸리므로, 중간에 적절하게 action 함수를 혼용해서 프로그래밍 한다.

- transformations 구문들은 chaining 하여 1라인으로 작성해도 된다.


- Spark 에서는 driver와 executors로 구성이 되고 이 둘 사이에는 통신을 한다.

- Spark Application 을 시작할때 SparkContext 생성으로 부터 시작되고 Master node에서는 동작 가능한 cores을 사용자의 spark application에 할당한다.

- 사용자는 보통 Spark Context를 사용해서 RDD 생성하고 사용한다.

- SparkContext 사용 방법 : sc = SparkContext(conf = conf)

- Partition 갯수 변경 및 확인 방법 : repartition(n), getNumPartitions() <- number만 지정해주면 spark이 알아서 분배해준다.

- python의 range(10,21) 함수는 선언 즉시 메모리를 할당하고 list 값을 갖지만, xrange 함수는 실행되는 시점에 메모리를 할당(lazy evaluation)한다.

- RDD의 lineage 확인하는 방법 : RDD.toDebugString()

- RDD의 type 확인하는 방법 : print 'type of RDD: {0}',format(type(RDD))


- map 함수를 사용하는 방법 : RDD.map(f), f 함수는 partition별로 처리할 로직의 함수이며 새로 생성되는 RDD는 동일한 partition 수를 갖는다.

- filter 함수를 사용하는 방법 : RDD.filter(f), f 함수는 true or false 값을 리턴해주어야 하며 true에 해당하는 data만 남게된다. data가 없어도 partition 수는 그대로 유지가 된다.

- reduce 함수는 파라메터로 function을 전달 받는데 이 function은 항상 associative(더하기 연산) 하고 commutative(곱하기 연산) 해야한다. (마이너스나 나누기 연산은 partition 변경에 따라 값이 달라지므로 사용 불가)

- takeSample 함수는 중복 허용 여부에 따라 num 갯수만큼 샘플링한다. seed 값을 사용하면 항상 같은 샘플링 값이 나오도록 할 수 있다.


- key/value 데이터의 경우에는 reduceByKey(f) 를 사용할 수 있다. 동일node의 같은key기준으로 병합한다. 이는 shuffling 할 때 네트워크 부하를 줄여주는 효과가 있다. (groupByKey()는 데이터가 많이 몰릴경우 네트워크 부하발생 및 out of memory가 발생할 수 있어 주의해야한다.)

- mapValues(sum) 이나 mapValues(list)를 사용해서 pySpark에서 처리도 가능하다.

- pySpark wordcount

text = sc.textFile("test")

wc = text.flatMap(lambda line : line.split()).map(lambda word : (word,1)).reduceByKey(lambda c1,c2 : c1+c2)

wc.collect()

print wc.sortByKey(ascending=True).collect()

print wc.map(lambda (w,c) : (c,w)).sortByKey(ascending=False).collect()

- file 기반의 검색 및 split 하기 위해서 정규화표현식(Regexp)을 사용한다.



(참고)

http://www.kocw.net/home/search/kemView.do?kemId=1174002

http://wiki.gurubee.net/pages/viewpage.action?pageId=28116079

http://hadoop.apache.org/

http://spark.apache.org/docs/latest/programming-guide.html

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using GooglePlayGames;

using UnityEngine.UI;


public class GoogleManager : MonoBehaviour {


public Text tx_id;

public Text tx_userName;

//public Text tx_Email;

public FacebookManager fb;


void Start()

{

PlayGamesPlatform.DebugLogEnabled = true;

PlayGamesPlatform.Activate ();

LogIn ();

}


public void LogIn()

{

Social.localUser.Authenticate ((bool success) => {

if (success) {

Debug.Log("You've successfully logged in");

tx_id.text = Social.localUser.id;

tx_userName.text = Social.localUser.userName;

//tx_Email.text = ((PlayGamesLocalUser)Social.localUser).Email + "-" + PlayGamesPlatform.Instance.GetUserEmail();

//fb.LogIn();

} else {

Debug.Log("Login failed for some reason : " + Social.Active);

Debug.Log("UserName : " + Social.localUser.userName);

Debug.Log("Id : " + Social.localUser.id);

}

/*

GooglePlayGames.OurUtils.PlayGamesHelperObject.RunOnGameThread(

() => {

Debug.Log("Local user's email is " + ((PlayGamesLocalUser)Social.localUser).Email);

});

*/

});

}


public void LogOut()

{

((PlayGamesPlatform)Social.Active).SignOut ();

tx_id.text = "No ID";

tx_userName.text = "No UserName";

//tx_Email.text = "No Email";

}

}



페이스북 앱을 만들었을경우 invitable_friends 를 가져 올수 있는데


유저의 해당 앱에 초대할 친구 목록이다 즉 가입이 안된 친구들 목록이다


나의 친구중


//해당앱에 초대된 유저

FB.API ("/me/friends?fields=id,name,picture", HttpMethod.GET, FriendListCallBack);

​//해당앱에 초대가 안된 유저 
FB.API ("/me/invitable_friends?fields=id,name,picture", HttpMethod.GET, InvitableFriendListCallBack);



​ using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using Facebook.Unity;
using Facebook.MiniJSON;



public class FBHolder : MonoBehaviour {
    public GameObject DialogLoggedIn;
    public GameObject DialogLoggedOut;
    public GameObject DialogUserName;
    public GameObject DialogPrifilePic;

    public GameObject FriendListGm;
    public GameObject Invitable_FriendListGM;

    private Dictionary<string,string> friendListDic;
    private Dictionary<string,string> invitable_friendListDic;

    void Awake(){
        FB.Init (SetInit, OnHideUnity);    
    }

    private void SetInit(){

        //Screen.SetResolution( Screen.width, Screen.width * 16 / 9, true );

        Debug.Log ("FB init donw");

        if (FB.IsLoggedIn) {
            Debug.Log ("Fb Logged In");
        } else {
            Debug.Log ("Fb Not Logged In");
        }

        //DealWidthFBMenu (FB.IsLoggedIn);
    }


    private void OnHideUnity(bool isGameShown){
        if(isGameShown){
            Time.timeScale = 0;
        }else{
            Time.timeScale = 1;
        }
    }

    public void FbLogin(){

        List<string> permissions = new List<string> ();
        permissions.Add ("public_profile");

        FB.LogInWithReadPermissions (permissions, AuthCallBack);
    }

    void AuthCallBack(IResult result){
        if (result.Error != null) {
            Debug.Log (result.Error);
        } else {
            if (FB.IsLoggedIn) {
                Debug.Log ("Fb Logged In AuthCallBack");

            } else {
                Debug.Log ("Fb Not Logged In AuthCallBack");
            }

            DealWidthFBMenu (FB.IsLoggedIn);
        }
    }



    void DealWidthFBMenu(bool isLoggedIn){
        if (isLoggedIn) {
            DialogLoggedIn.SetActive (true);
            DialogLoggedOut.SetActive (false);

            FB.API ("/me?fields=first_name", HttpMethod.GET, DialogUserNameCallBack);
            FB.API ("/me/picture?type=square&height=128&width=128", HttpMethod.GET, DialogUserProfileImgCallBack);
            FB.API ("/me/friends?fields=id,name,picture", HttpMethod.GET, FriendListCallBack);
            FB.API ("/me/invitable_friends?fields=id,name,picture", HttpMethod.GET, InvitableFriendListCallBack);
        } else {
            DialogLoggedIn.SetActive (false);
            DialogLoggedOut.SetActive (true);
        }
    }


    void DialogUserNameCallBack(IResult result){
        Text UsetName = DialogUserName.GetComponent<Text> ();

        if (result.Error == null) {
            UsetName.text = "Hi there, " + result.ResultDictionary ["first_name"];
        } else {
            Debug.Log (result.Error);
        }
    }

    void DialogUserProfileImgCallBack(IGraphResult result){
        

        if (result.Texture != null) {
            Image ProfilePic = DialogPrifilePic.GetComponent<Image> ();
            ProfilePic.sprite = Sprite.Create (result.Texture, new Rect (0, 0, 128, 128), new Vector2 ());
        } else {
            Debug.Log (result.Error);
        }
    }


    //게임등록을 안한 유저 
    void InvitableFriendListCallBack(IResult result){
        if (result.Error != null) {
            Debug.Log ("Error : " + result.Error);
        } else {
            invitable_friendListDic =  FriendListParsing.Parsing (result.RawResult);
            SetText ( Invitable_FriendListGM , invitable_friendListDic);
        }
    }


    //게임등록을  유저 
    void FriendListCallBack(IResult result){
        if (result.Error != null) {
            Debug.Log ("Error : " + result.Error);
        } else {
            friendListDic = FriendListParsing.Parsing (result.RawResult);
            SetText (FriendListGm, friendListDic);
        }
    }


    //리스ㅌ트를 텍스트로 뿌려준다 
    void SetText(GameObject gm, Dictionary<string,string> dic){
        Text textField = gm.GetComponent<Text> ();
        foreach (KeyValuePair<string,string> pair in dic) {
            textField.text += string.Format ("{0}", pair.Key, pair.Value)+"\n";
        }
    }


        


}

파싱용 스크립트


using Facebook.MiniJSON;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using Facebook.Unity;

public class FriendListParsing {



    //친구 리스트 파싱 
    static public Dictionary<string,string> Parsing(string text){
        Debug.Log ("parsing " + text);

        //이곳에 json이 담겨져 있ㅏ 
        Dictionary<string, object> dict = (Dictionary<string,object>)Json.Deserialize (text);

        object friendsH;
        List<object> friends = new List<object> ();
        string friendName;

        Dictionary<string,string> friend = new Dictionary<string,string> ();

        if (dict.TryGetValue ("data", out friendsH)) {
            friends = (List<object>)dict ["data"];

            if (friends.Count > 0) {

                for (int i = 0; i< friends.Count; i++) {
                    Dictionary<string,object> friendDict = ((Dictionary<string,object>)(friends [i]));

                    friend [(string)friendDict ["name"]] = (string)friendDict ["name"];

                }
            }
        }


        return friend;
    }
}



http://blog.naver.com/brane7/220712830773


'Program > Unity' 카테고리의 다른 글

google sdk  (0) 2017.02.23
[Unity3D] Application.LoadLevel(string) is obsolete 마이그레이션  (0) 2017.02.20

http://ts-endingpopup.yjmgames.net:10574/service.php?packet_id=Ending&ssn=2&bundleid=com.bundleid.nohero.ios&market=12&country=EN


http://endingpopup.yjmgames.net:10574/service.php?packet_id=Ending&ssn=2&bundleid=com.bundleid.nohero.ios&market=12&country=EN


http://ts-notice.yjmgames.net:10574/service.php?packet_id=Notice&ssn=2&bundleid=com.bundleid.nohero.ios&market=12&country=EN


http://terms.yjmgames.net:10574/service.php?packet_id=Terms&ssn=2&bundleid=com.bundleid.nohero.ios&market=12&country=EN


http://ts-terms.yjmgames.net:10574/service.php?packet_id=Terms&ssn=2&bundleid=com.bundleid.nohero.ios&market=12&country=EN


http://ts-terms.yjmgames.net:10574/service.php?packet_id=Notice&ssn=2&bundleid=com.bundleid.nohero.ios&market=12&country=EN


http://notice.yjmgames.net:10574/service.php?packet_id=Notice&ssn=2&bundleid=com.bundleid.nohero.ios&market=12&country=EN


http://ts-iws.yjmgames.net:10574/state.php?packet_id=Iws&ssn=1&bundleid=com.bundleid.nohero.aos&market=2&version=1.01



http://52.78.177.195:10574/main_server.php?packet_id=Iws&ssn=1&bundleid=com.bundleid.nohero.aos&market=2&version=1.01

http://worksp.tistory.com/10



유니티 5.3.1 f1 로 버전업 했더니, NGUI 에서 범상치 않은 워닝을 내뱉었다.


1
2
3
Assets/NGUI/Examples/Scripts/Other/LoadLevelOnClick.cs(15,37): 
warning CS0618: `UnityEngine.Application.LoadLevel(string)' is obsolete: 
`Use SceneManager.LoadScene'

cs



Application.LoadLevel 로 씬 이동 하던 것을 SceneManager.LoadScene 으로 사용하란다.


그래서 유니티의 바람대로 SceneManager.LoadScene 으로 고쳐썼더니 네임스페이스가 없다고 한다....


검색해보니 UnityEngine.SceneManagement 라는 네임 스페이스가 추가된 듯.. 



1
using UnityEngine.SceneManagement;
cs


위와 같이 네임스페이스를 추가하니 정상적으로 작동한다.




알고보니 유니티 5.3에서 멀티 씬 편집(Multi-Scene Editing) 을 지원한다고 한다.


아래와 같이 프로젝트 뷰 에서 오른쪽 클릭을 한 후, Open Scene Additive 를 클릭하면...




▼ 이렇게 하이라키 뷰에 여러 씬이 열린다.






또한 SceneManager 추가되었고, 덕분에 자주쓰는 메소드들도 거의 다 구식이 되어버렸다.


변경점은 다음과 같다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// old
Application.LoadLevel(0);                                       // 로드. 
Application.LoadLevel("SceneName");
AsyncOperation ao = Application.LoadLevelAsync(0);              // 로드. (비동기)
AsyncOperation ao = Application.LoadLevelAsync("SceneName");
Application.LoadLevelAdditive(0);                               // 씬 병합 추가. 
Application.LoadLevelAdditive("SceneName");
Application.LoadLevelAdditiveAsync(0);                          // 씬 병합 추가. (비동기)
Application.LoadLevelAdditiveAsync("SceneName");
Application.UnloadLevel(0);                                     // 언로드. 
Application.UnloadLevel("SceneName");
Application.levelCount;                                // BuildSetting 에 등록 된 씬 개수. 
Application.loadedLevel;                                        // 현재 씬 인덱스. 
Application.loadedLevelName;                                    // 현재 씬 이름. 
 
// 5.3
SceneManager.LoadScene(0);                                      // 로드. 
SceneManager.LoadScene("SceneName");
AsyncOperation ao = SceneManager.LoadSceneAsync(0);             // 로드. (비동기)
AsyncOperation ao = SceneManager.LoadSceneAsync("SceneName");
SceneManager.LoadScene(0, LoadSceneMode.Additive);              // 씬 병합 추가. 
SceneManager.LoadScene("SceneName", LoadSceneMode.Additive);
SceneManager.LoadSceneAsync(0, LoadSceneMode.Additive);         // 씬 병합 추가. (비동기)
SceneManager.LoadSceneAsync("SceneName", LoadSceneMode.Additive);
SceneManager.UnloadScene(0);                                    // 언로드. 
SceneManager.UnloadScene("SceneName");
SceneManager.sceneCount;                                        // 현재 로드 된 씬 개수. 
SceneManager.sceneCountInBuildSettings;                // BuildSetting 에 등록 된 씬 개수. 
SceneManager.GetActiveScene().buildIndex;                       // 현재 씬 인덱스. 
SceneManager.GetActiveScene().name;                             // 현재 씬 이름. 
 
// 씬 정보 조회. 
Scene activeScene = SceneManager.GetActiveScene();
Scene scene1 = SceneManager.GetSceneAt(0);
Scene scene2 = SceneManager.GetSceneByName("SceneName");
Scene scene3 = SceneManager.GetSceneByPath("Assets/SceneName.unity");
Scene[] loadedScenes = SceneManager.GetAllScenes();
 
// Scene 구조체. 
int buildIndex;
string name;
string path;
bool isLoaded;
bool isDirty;       // 씬을 변경(수정)했는지 여부. 
int rootCount;      // 씬의 Root에 있는 GameObject 개수. 
bool IsValid();     // 유효한 씬인지 여부. 
 
// 기타. 
Scene scene = gameObject.scene;                 // 게임오브젝트가 속해있는 씬을 가져오기. 
GameObject go = new GameObject("New Object");   // 게임오브젝트를 생성하면 현재 씬에 추가 됨. 
SceneManager.MoveGameObjectToScene(go, scene);      // 게임오브젝트를 다른 씬으로 이동. 
SceneManager.MergeScenes(sourceScene, destinationScene);    // 씬을 병합. 
 
// SceneManager.Get~() 으로 가져올 수 있는 것은 로드가 끝난 씬만 가능. 
Scene scene = SceneManager.GetSceneByName("SceneName");
bool isValid = scene.IsValid();     // false 가 리턴 됨.
cs



정리하다보니 꽤 많네;;;


아, 그리고 DontDestroyOnLoad 메소드 비스므리 한 것은 아예 없었는데,


Tips 를 참조해 보면, DontDestroyOnLoad 의 사용은 피하는 것이 좋고, Manager 씬을 만들어서 병합하는 것이 좋다고 한다.


앞으로 개발 시 참고해야 할 사항인 것 같다.



PS. Unity 5.3 에서는 과금 플러그인을 이용할 필요가 없을 수도 있겠다.


Unity Service Tab 에서 여러가지를(Unity Ads, Analytics, Cloud Build, In-App Purchasing, Multiplayer) 지원함..




'Program > Unity' 카테고리의 다른 글

google sdk  (0) 2017.02.23
Facebook - 로그인 - 친구리스트 불러오기  (0) 2017.02.23


https://g3n1k.wordpress.com/2016/10/03/cannot-create-mssql-so-on-ubuntu-16-04-and-php5-6/


using php5.6 with freetds installed, and use ubuntu server 16.04

sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install apache2 mysql-server php5.6 php5.6-mbstring php5.6-mcrypt php5.6-mysql php5.6-xml php5.6-cli libapache2-mod-php5.6 php5.6-gd freetds-common freetds-bin unixodbc php5.6-sybase php5.6-odbc cifs-utils php5.6-curl

how i know which mssql not working ???

  • try with phpinfo
    sudo nano /var/www/html/info.php
    # paste this code
    <?php phpinfo(); ?>

    open with browser, but i can find mssql there

  • try with php code
    sudo nano /var/www/html/ms.php
    # paste this code
    <?php
    $connection = mssql_connect('mssql-host', 'mssql-user', 'mssql-pass');
    if (!$connection) { die('Unable to connect!'); }
    if (!mssql_select_db('mssql-db', $connection)) { die('Unable to select database!');}
    $result = mssql_query('SELECT * FROM CAPACITY_INFO');
    while ($row = mssql_fetch_array($result)) { var_dump($row); }
    mssql_free_result($result);
    ?>
    # then try
    php /var/www/html/ms.php

    php-mssql

  • success try with tsql

tsql

  • cannot find mssql.so in /usr/lib/php/20131226/
    ls /usr/lib/php/20131226/ | grep mssql

 how to solve

# download the mssql.so
# this mssql get from ubuntu server 64 bit and php 5.6
https://drive.google.com/open?id=0BxV3_TI0LIeYT2pzVzBXRG1sVWM

#upload to your server
scp mssql.so user@server:/home/youruserhome

# move mssql.so to /usr/lib/php/20131226/
sudo mv /home/youruserhome/mssql.so /usr/lib/php/20131226/

# create mssql.ini
sudo nano sudo /etc/php/5.6/mods-available/mssql.ini

# insert this code
extension=mssql.so
# save and close

# copy config mssql.ini 
cd /etc/php/5.6/apache2/conf.d
sudo ln -s /etc/php/5.6/mods-available/mssql.ini 20-mssql.ini
cd /etc/php/5.6/cli/conf.d
sudo ln -s /etc/php/5.6/mods-available/mssql.ini 20-mssql.ini

# restart service apache2
sudo service apache2 restart

test again with phpinfo and script

mssql-phpinfo

success


'Program > PHP' 카테고리의 다른 글

php, mysql_fetch_assoc 결과를 json 문자열로 만들기  (0) 2017.10.28
API  (0) 2017.02.21
PHP7 에서 PHP5.6 사용하기  (0) 2016.11.11
SQL Relay php connection  (0) 2016.07.17
PHP PHP EXCEL (PHP 엑셀 읽기 쓰기)  (0) 2016.01.21

ubuntu 16.04LTS를 설치하면 php가 자동으로 최신버전인 7.0이 설치가 됩니다.


하지만 php 7버전에서 php 은닉기능인 AddType application/x-httpd-php이 잘 되지 않습니다.






이런식으로 php가 그대로 출력되어 깨집니다.


2일정도 방법을 찾다보니 5.6버전을 사용할 수 있는 방법이 있어 공유합니다.


1. apache proxy module을 중지시킵니다.


1
sudo a2dismod proxy_fcgi proxy
cs





2. php 5.6버전을 설치합니다.


reopsitory에 php5를 설치할 수 있도록 추가하고 업데이트 해줍니다.



1
2
3
sudo add-apt-repository ppa:ondrej/php
 
sudo apt-get update
cs





이제 php를 설치합니다. 5.6뿐만아니라 7.0도 같이 설치합니다.


1
sudo apt-get install php7.0 php5.6 php5.6-mysql php-gettext php5.6-mbstring php-xdebug libapache2-mod-php5.6
libapache2-mod-php7.0



이렇게 설치해 놓으면 필요에 따라 php 7과 php 5.6을 모두 사용 가능 합니다.


3. 사용할 php 선택하기


이 부분이 제일 중요합니다.


기존 php중지-> 새로운 php 시작 -> apache 재시작


순서로 진행하면 됩니다.


i) php5.6 사용하기


a)php7.0 중지


1
sudo a2dismod php7.0
cs




b)php5.6 사용


1
sudo a2enmod php5.6
cs



c)apache 재시작


1
sudo service apache2 restart
cs



이제 웹페이지를 실행해 보면 html속의 php가 정상 동작합니다.





ii) php7.0 사용하기


반대로 php7.0을 사용하려면 위와 반대로 명령을 내리면 됩니다.


a)php5.6 중지


1
sudo a2dismod php5.6
cs



b)php7.0 사용


1
sudo a2enmod php7.0
cs


c)apache 재시작


1
sudo service apache2 restart
cs



참고로 apache 서버가 아니고 CLI의 경우 아래의 코드를 입력하세요.


php 5.6 => php 7.0


1
sudo ln -sfn /usr/bin/php7.0 /etc/alternatives/php
cs



php 7.0 => php 5.6


1
sudo ln -sfn /usr/bin/php5.6 /etc/alternatives/php
cs



그리고 php의 경로가 /etc/php/ 밑에 버전별로 되어있습니다.









'Program > PHP' 카테고리의 다른 글

API  (0) 2017.02.21
cannot create mssql.so on ubuntu 16.04 and php5.6  (0) 2017.02.17
SQL Relay php connection  (0) 2016.07.17
PHP PHP EXCEL (PHP 엑셀 읽기 쓰기)  (0) 2016.01.21
ubuntu php에서 redis사용하기 - Predis  (0) 2015.05.28

Python

Using the Python DB API, don't do this:

# Do NOT do it this way.
cmd = "update people set name='%s' where id='%s'" % (name, id)
curs.execute(cmd)

Instead, do this:

cmd = "update people set name=%s where id=%s"
curs.execute(cmd, (name, id))

Note that the placeholder syntax depends on the database you are using.

'qmark'         Question mark style,
                e.g. '...WHERE name=?'
'numeric'       Numeric, positional style,
                e.g. '...WHERE name=:1'
'named'         Named style,
                e.g. '...WHERE name=:name'
'format'        ANSI C printf format codes,
                e.g. '...WHERE name=%s'
'pyformat'      Python extended format codes,
                e.g. '...WHERE name=%(name)s'

The values for the most common databases are:

>>> import MySQLdb; print MySQLdb.paramstyle
format
>>> import psycopg2; print psycopg2.paramstyle
pyformat
>>> import sqlite3; print sqlite3.paramstyle
qmark

So if you are using MySQL or PostgreSQL, use %s (even for numbers and other non-string values!) and if you are using SQLite use ?



ImportError: No module named 'MySQLdb'


파이썬 3.5에서는 아직 지원하지 않는다.

mysqlclient를 사용하자


apt-get install libmysqlclient-dev

pip3 install mysqlclient

[유저관련 지표]

  • UV (Unique visitor) : 일정기간 내에 게임의 접속(방문)한 실제 유저 수로 한 유저가 여러번 방문해도 1로 카운트 한다.

  • DAU (Daily Active User) : 일단위로 측정한 UV

  • WAU (Week Active User) : 주단위로 측정한 UV

  • MAU (Monthly Active User) : 월 단위로 UV 측정

  • RU (Registered User) : 일정기간내에 게임에 등록된 유저 수

  • NRU (New Registered User) : 일정기간내에 등록된 신규 유저 수.

  • ARU (Accumulate Register User): 해당 기간까지의 등록된 누적 유저 수

  • 재방문 UV : 해당 기간 동안 게임 클라이언트에 2회 이상 로그인한 회원 수

  • MUV (Multigame Unique Visitor): 해당 기간 동안 게임 클라이언트에 로그인하여 실제 게임을 플레이 한 회원 수

  • MTS (Mutigame Time Spent): 해당 기간 동안의 평균 실제 플레이 타임

  • TS(Time Spent) : 해당기간 동안의 유저1인당 플레이 타임

  • CCU (Concurrent User) : 특정 시점에 접속한 동시 접속자 수

  • MCU (Maxium Concurrent User) : 하루 동안 가장 높은 동시접속자 수치.

  • PCU (Peak Concurrent User) : MCU 동일어

  • ACU (Average Concurrent User) : 1일 동안의 평균 동시 접속자 수

  • Stickness : 고착도

  • EU (Executed User) : 인게임을 플레이한 유저로 UV와 같이 비교대상으로 분석

 

 

 [매출 관련 지표]

  • BU (Buying user) : 구매유저일정기간내에 게임에 아이템 구매월정액 결제 등 돈을 지불한 유저

  • PU (Paying User) : BU 동일어

  • BU rate = BU/UV (순방문자대비 결제 유저 비율)

  • CAC(Customer Acquisition Cost) : 유저 확보 비용으로 유저 1인을 확보하는데 소모되는 비용

  • CRC (Customer Retention Cost) : 유저 유지 비용으로 일정기간내에 유저1인을 유지하는데 소모되는 비용

  • ARPU (Average Revenue Per User) : 일정 기간 내 유저 1인당 평균 수입

  • ARPPU (Average Revenue Per Paying User) : 일정 기간내에 게임에 비용을 지불한 유저의 1인당 평균 수입

  • PPU (Percentage of Paying Users) : DAU 내에서 결제한 비율 또는 비율

  • LTV (Life time value) : 유저 1인당 게임에서 완전히 이탈할 때까지 지불하는 비용

  • Entry Cost : 여러 가지 가격대의 상품을 제공할 때 유저의 최초 구매가 어떤 가격대에서 많이 일어나는지 측정

  • Sales by Purchase : 사용자의 구매 활동을 통해 집계된 매출

  • Sales by Advertisement : 광고 노출을 통해 집계된 매출

  • CPI (Cost per Install) : 게임 다운로드 후 설치하면 보상

  • CPA (Cost per Action) : 설치된 앱을 실행하면 보상

  • CPP (Cost per Play) : CPA 이후 일정 기간 한번씩 실행할 때마다 보상

  • CPL (Cost per Level) : 정량적인 플레이에 대한 레벨을 설정한 뒤 보상

 

 

[투자 퍼블리싱 관련 용어]

MOU (Memorandum of understanding) : 투자 등 거래에 관해 합의한 사항을 명시한 사전 협의문서로 법적 구속력이 없으며 정식 계약 전 업무 준비/친선관계 개선/대외 홍보의 역할로 활용 한다.

Initial fee : 판권 제공/계약 체결 시 판권 부여를 대가로 수령하는 금액으로 흔히 계약금이라고 한다.

Running Royalty : 퍼블리셔가 개발사에게 매출액의 일정 비율을 지급하는 비용으로 러닝 개런티랑 동일하다.

MG(Minimum Guarantee) :  판권 제공자의 최소 러닝 로얄티를 보장해 주는 금액

RS (Revenue Share) : 판권제공사/퍼블리셔 간의 수익 분배 비율

PF (Project Financing) : 회사 지분에 대한 투자가 아닌 프로젝트 성공 수익에 대해 투자하는 투자 방식

KPI(Key Performance Indicator) : 핵심실행지표로 기업이나 조직의 목표달성과 전략을 위한 핵심측정지표

 

 

[참고자료]

http://blog.naver.com/minopie/220362749342

 

 

용어는 업계마다 약간씩 다르지만 의미는 거의 유사하기 때문에 정리된 내용을 알아두면 많은 도움이 되리라 생각한다앞으로 포스팅 예정인 게임 통계 내용도 정리된 용어를 기반으로 설명한다.

 

 

 

게임마케팅게임용어마케팅 용어게임기획게임 분석게임이야기마케팅이야기동시접자수재방문율결제유저, ARPU, ARPPU, DAU, NU, UV, PV MCU, PCU, CCU


'연구개발 > Etc..' 카테고리의 다른 글

[Docker] 생성 및 실행  (0) 2018.07.04
운영체제 개론  (0) 2017.05.29
unity key  (0) 2016.05.07
RAID 1+0 과 0+1의 차이점  (0) 2011.07.11
윈도우 보안취약점 보완 강화  (0) 2011.05.04

공개커넥션 풀 프로그램 설명
http://tunelinux.pe.kr
http://database.sarang.net
2004.12.24
문태준

커넥션 풀은 프로그램(java, c, php 등등)과 db사이에서 db연결을 pool로 만들어 제어해주는 것입니다.
PHP에서 사용할 수 있는 공개 커넥션 풀 프로그램을 찾은 것이 있어서 여기 올립니다.
여기서는 간단한 사용법만 설명합니다. 자세한건 설명서와 옵션을 열심히 보고 고민해야 할듯.

구조는 다음과 같습니다.
db접속요청 -> 커넥션 풀 대몬 -> db 접속
db접속요청이 늘어나도 db 프로세스 갯수는 일정합니다. 커넥션 풀을 이용하여 자원관리를 하는 것입니다.

SQL Relay
http://sqlrelay.sourceforge.net/

SQL Relay is a persistent database connection pooling, proxying and load balancing system for Unix and Linux.

지원 DB는 다음과 같습니다.
* Oracle
* MySQL
* mSQL
* PostgreSQL

* Sybase
* MS SQL Server
* IBM DB2
* Interbase

* Sybase
* SQLite
* Lago
* ODBC

지원 api
* C
* C++
* Perl

* Python
* PHP
* Ruby

* Java
* TCL
* Zope

설치방법
http://sqlrelay.sourceforge.net/download.html 에서 SRPM을 이용하여 새로 RPM을 만들었습니다.
설치설명서를 참고하면 여러가지 방법을 이용할 수 있습니다. http://sqlrelay.sourceforge.net/sqlrelay/installing.html

SRPM을 설치하고 RPM을 만들때 여러가지 RPM파일을 요구합니다. 나오는 내용을 보고 설치해주면 됩니다.
gtk-devel 등등.

PHP를 사용하는데 소스로 설치했더니 php-config (php 확장모듈 만들때 쓰지요?) 를 못 찾더군요. 아마도 경로를 지정해주면 될듯한데 그냥 귀찮아서 php rpm을 설치하였습니다. 임시테스팅이 목적이었으므로.

설치시 불필요한 db, api를 명시해주지 않으면 rpm을 만들다가 에러가 납니다.

rpm -ta -without oracle -without zope sqlrelay-xxx.tar.gz

위와 같은 식입니다.

rpmbuild -without db2 -without freetds --without oracle -without zope sqlrelay.spec

나온 파일을 필요에 따라 설치합니다.

[root@kdu i386]# ls -1 
sqlrelay-0.35-1.i386.rpm
sqlrelay-client-devel-c-0.35-1.i386.rpm
sqlrelay-client-devel-c++-0.35-1.i386.rpm
sqlrelay-client-mysql-0.35-1.i386.rpm
sqlrelay-client-postgresql-0.35-1.i386.rpm
sqlrelay-client-runtime-c-0.35-1.i386.rpm
sqlrelay-client-runtime-c++-0.35-1.i386.rpm
sqlrelay-clients-0.35-1.i386.rpm
sqlrelay-config-gtk-0.35-1.i386.rpm
sqlrelay-doc-0.35-1.i386.rpm
sqlrelay-man-0.35-1.i386.rpm
sqlrelay-mysql-0.35-1.i386.rpm
sqlrelay-perl-0.35-1.i386.rpm
sqlrelay-php-0.35-1.i386.rpm

# rpm -ivh *.rpm

# rpm -ql sqlrelay | grep bin
/usr/bin/sqlr-cachemanager
/usr/bin/sqlr-listener
/usr/bin/sqlr-listener-debug
/usr/bin/sqlr-scaler
/usr/bin/sqlr-start
/usr/bin/sqlr-stop

# rpm -ql sqlrelay-php
/usr/lib/php4/sql_relay.so -> 이게 php모듈이지요.
/usr/share/pear/DB/sqlrelay.php

sqlrelay rpm으로 설치를 하면 /etc/sqlrelay.conf 파일을 만들어 설정합니다.
샘플은 /etc/sqlrelay.conf.example 입니다.

# ls /etc/sqlrelay.*
/etc/sqlrelay.conf /etc/sqlrelay.conf.example /etc/sqlrelay.dtd

아래와 같이 임시로 세팅했습니다.

mysql 의 경우 최소 수정할것 
id : instance id. sqlr-start 할때 필요함
dbase : mysql
connections : 초기 연결할 갯수
maxconnections : 최대 접속자

users 는 해당 api에서 접속할때 필요한 사용자, 비밀번호입니다. 나중 php소스코드보면 이해감.

connections는 커넥션 풀을 만들때 사용하는 db, user 등의 정보임.

<?xml version="1.0"?>
<!DOCTYPE instances SYSTEM "sqlrelay.dtd">

<instances>

<instance id="example" port="9000" socket="/tmp/example.socket" dbase="mysql" connections="20" maxconnections="500" maxqueuelength="5" growby="1" ttl="60" endofsession="commit" sessiontimeout="600" runasuser="nobody" runasgroup="nobody" cursors="5" authtier="listener" handoff="pass" deniedips="" allowedips="" debug="none">
<users>
<user user="user1" password="password1"/>
<user user="user2" password="password2"/>
<user user="user3" password="password3"/>
</users>
<connections>
<connection connectionid="db1" string="user=aaaat;password=aaaa;db=test;host=localhost;port=3306;socket=/var/lib/mysql/mysql.sock;" metric="1"/>
<connection connectionid="db2" string="user=aaaa;password=aaaa;db=test;host=localhost;port=3306;socket=/var/lib/mysql/mysql.sock;" metric="1"/>
<connection connectionid="db3" string="user=aaaa;password=aaaa;db=test;host=localhost;port=3306;socket=/var/lib/mysql/mysql.sock;" metric="1"/>

</connections>
</instance>

</instances>

이제 커넥션풀을 시작합니다.
# sqlr-start -id example -config /etc/sqlrelay.conf

# ps auxw | grep sqlr
nobody 20725 0.0 0.2 3600 1408 ? S 16:11 0:00 sqlr-listener -id example -config /etc/sqlrelay.conf
nobody 20728 0.0 0.3 4288 1720 ? S 16:11 0:00 sqlr-connection-mysql -id example -connectionid db1 -config /etc/sqlr
nobody 20731 0.0 0.3 4292 1720 ? S 16:11 0:00 sqlr-connection-mysql -id example -connectionid db1 -config /etc/sqlr
nobody 20734 0.0 0.3 4292 1720 ? S 16:11 0:00 sqlr-connection-mysql -id example -connectionid db1 -config /etc/sqlr
nobody 20785 0.0 0.3 4288 1720 ? S 16:11 0:00 sqlr-connection-mysql -id example -connectionid db5 -config /etc/sqlr
nobody 20787 0.0 0.2 3572 1368 ? S 16:11 0:00 sqlr-scaler -id example -config /etc/sqlrelay.conf
root 20793 0.0 0.2 3488 1072 ? S 16:11 0:00 sqlr-cachemanager

위에서 보듯이 몇가지 프로세서로 이루어집니다.

끝내기
# sqlr-stop 
id를 지정하지 않으면 몽땅 죽입니다.

mysqladmin pro 에서 보면 connections 만큼 mysql 과 연결되어있습니다.

샘플코드 php

# cat sql.php 
<?
dl("sql_relay.so");

$con=sqlrcon_alloc("localhost",9000,"","user1","password1",0,1) or die ("connect error");
$cur=sqlrcur_alloc($con);

echo "sendquery";
sqlrcur_sendQuery($cur,"select * from test");

#sqlrcur_sendFileQuery($cur,"/usr/local/myprogram/sql","myquery.sql");
echo "endsession";
sqlrcon_endSession($con);

sqlrcur_sendQuery($cur,"select * from test");
sqlrcon_endSession($con);

sqlrcur_free($cur);
sqlrcon_free($con);
?>

사이트에 나온 소스코드에서는 아래와 같이 나와있는데 " 를 넣어주지 않으면 에러가 납니다. ; 도 빠져있구요.
dl(sql_relay.so)

** 기타참고사이트
http://sqlb.sourceforge.net/frameset.html
The SQLB project is used to improve SQL requests to a database. It supports MySQL, PostgreSQL and Oracle(tm).

It is a set of deamon programs that make multiple permanent connection to one or more database when they start. Then an external program, previously linked with the sqlb client library, can send SQL requests to these deamons and get the result without any need to make a connection/disconnection. The SQLB PHP and Perl modules provided here with SQLB are some examples of such programs.

** phpschool 참고자료
http://www.phpschool.com/bbs2/inc_view.html?id=6888&code=tnt2 : Too many connections 에러와 DB pool 사용
http://www.phpschool.com/bbs2/inc_view.html?id=8132&code=tnt2 : 새로운 요청 처리 방법
http://www.phpschool.com/bbs2/inc_view.html?id=10093&code=tnt2 : 데이터베이스 풀링에 대한 sqlrelay 설치 문서

'Program > PHP' 카테고리의 다른 글

cannot create mssql.so on ubuntu 16.04 and php5.6  (0) 2017.02.17
PHP7 에서 PHP5.6 사용하기  (0) 2016.11.11
PHP PHP EXCEL (PHP 엑셀 읽기 쓰기)  (0) 2016.01.21
ubuntu php에서 redis사용하기 - Predis  (0) 2015.05.28
php 기본 내용  (0) 2015.05.27

MS-SQL 에서 MY-SQL 서버를 연결된 서버 ( Linked Server ) 로 등록하는 방법 


1. 제어판 - 관리 도구 - 데이터 원본(ODBC) 실행.

( mysql ODBC 설치가 안되어 있다면 http://dev.mysql.com/downloads/connector/odbc/Viewer 환경에 맞는 ODBC 설치 )






2. SSMS 에서 연결된 서버 - 새 연결된 서버 선택





3. 아래와 같이 입력.


일반 탭



보안 탭




완료 후 테스트 방법은 

OpenQuery 를 이용해서 쿼리를 날려봅니다.


오픈 쿼리에 대한 정보는 http://msdn.microsoft.com/ko-kr/library/ms188427.aspxViewer

+ Recent posts