====== 컴퓨터 개념원리 정리 ====== 대학원 랩실 면접을 대비해서 컴퓨터의 전체적인 개념원리에 대해서 정리했다. 특히 '초보 프로그래머가 꼭 알아야할 컴퓨터의 동작원리' 라는 책을 많이 참고 했다. ====== 컴퓨터의 구성 ====== 각각의 디바이스들은 버스라는 통로로 연결되어 있다. | 이름 | 설명 | | 어드레스 버스 | 메모리 주소가 전달된다 | | 데이터 버스 | 데이터가 전달된다 | | 제어 버스 | 제어정보가 전달된다 | ===== 프로그램의 CPU 에서의 실행순서 ===== '소스프로그램 컴파일 -> 기계어 코드로 변환(바이너리) -> 메인 메모리에 적재(프로세스 상태) -> CPU 에서 한줄씩 읽어서 실행' ====== CPU 의 구성 ====== | 이름 | 설명 | | 제어장치 | 명령어를 해석하고 다른 장치들에게 동작을 지시한다 | | 연산장치 | 덧셈, 뺄셈등의 연산을 한다 | | 레지스터 집합 | 명령어를 실행하는 동안 필요한 정보들을 저장한다 | ===== 레지스터의 종류 ===== | 이름 | 설명 | | 어드레스 레지스터 | 메모리로 부터 데이터를 읽거나 데이터를 쓸 메모리 주소를 저장 | | 프로그램 카운터 | 다음에 실행할 명령어가 저장될 메모리주소를 저장 | | 데이터 레지스터 | 메모리에서 읽어온 데이터를 저장 | | 명령어 레지스터 | 메모리에서 읽어온 명령어를 저장 | | 어큐뮬레이터 | 연산에 사용되는 데이터를 저장 | ex) 프로그램이 실행되는 예제 | 카운터 | 명령어 | | 101 | LOAD 104 | | 102 | ADD 105 | | 103 | STORE 106 | | 104 | 200 | | 105 | 300 | - 프로그램 카운터에 저장되어 있는 값인 101 을 어드레스 레지스터에 저장 - 제어장치가 읽기제어 신호를 보내 어드레스 레지스터에 저장되어 있는 101번지의 명령어인 'LOAD 104' 를 읽어 명령어 레지스터에 저장 - 프로그램 카운터를 1 증가시킴, 제어 장치가 명령어 레지스터의 명령어를 해독하고 104 번지의 데이터를 읽어올 필요성을 느껴 어드레스 레지스터에 104 를 저장 - 제어장치가 읽기제어 신호를 보내 어드레스 레지스터에 저장되어 있는 104 번지의 데이터인 '200' 을 읽어 데이터 레지스터에 저장 - 데이터 레지스터에 저장된 '200' 을 연산장치를 경유해서 연산에 사용되는 데이터를 저장하는 레지스터인 어큐뮬레이터로 저장 - 101번지 명령어에 대한 실행이 모두 끝났으므로 다음 명령어인 102 번지 명령어를 실행 ====== 파이프 라이닝과 수퍼스칼라 ====== | 파이프 라이닝 | 명령어를 실행하는 과정을 여러단계로 나누어 여러 명령어를 동시에 실행함으로써 CPU 속도를 빠르게 하는 기술 | ===== 발생할 수 있는 문제 ===== 처리 도중에 각 변수들의 값이 변할 수 있다. (a=b; c=a;) ===== 해결책 ===== 처리 중간에 아무 동작도 하지 않는 NOP 명령어를 삽입한다. 명령어의 순서를 재배치한다. | 수퍼스칼라 | CPU 내에 파이프라인을 여러개두어 여러 명령어를 동시에 실행하는 기술(병렬처리) | ====== 캐시 메모리 ====== 자주 참조되는 프로그램과 데이터를 메인 메모리가 아닌 더욱 빠른 속도의 메모리에 저장해두면, 메모리 접근시간이 감소해 결국 프로그램의 실행시간이 단축될 것이다.(일반적으로 CPU 와 메인 메모리 사이에 위치한다. 최근에는 CPU 를 포함하고 있는 칩안에 위치하기도 한다. SRAM 으로 구현) ===== 동작 설명 ===== - CPU 가 101번지 워드를 필요로 하면 우선 캐시 메모리에 해당 워드가 있는지 조사한다. - 찾는 워드가 있으면 히트(HIT), 없으면 미스(MISS) 이다. - 우선 메인 메모리로 부터 101 번지 워드를 포함하고 있는 블록을 캐시 메모리로 전송하고, 캐시메모리로 부터 101번지 워드를 CPU 로 전달한다. - 이 때 메인 메모리로 부터 캐시 메모리로의 전송은 블록단위로 이루어지고, 캐시 메모리로 부터 CPU 로의 전송은 워드 단위로 이루어 진다. ===== 쓰기 정책(캐시 메모리의 저장된 데이터가 수정되었을 때 반영하는 방법) ===== | 나중쓰기 방식 | 저장된 데이터가 바뀌더라도 캐시메모리상의 데이터만 수정되다가 더이상 데이터의 참조가 필요없게 되면 그때 메인 메모리에 저장 | | 장점 | 메인 메모리에 반영하는 동작을 최소화 함으로써 성능이 좋음 | | 단점 | 수정된 내용이 메인 메모리에 반영되지 않아 메인 메모리 데이터가 의미가 없음 | | 즉시쓰기 방식 | 데이터가 바뀔때마다 메인 메모리의 데이터도 수정 | | 장점 | 캐시 메모리와 메인 메모리가 항상 같은 데이터를 가짐 | | 단점 | 너무 자주 메인 메모리에 접근하므로 성능 저하를 가져옴 | ===== 멀티 프로세서에서의 캐시 일관성 유지하기 ===== 각각의 CPU 마다 캐시메모리를 가지고 있다. 이 상태에서 하나의 데이터 값이 각각의 CPU 캐시 메모리마다 다를때 이때 데이터 값을 수정한 CPU 의 캐시 메모리를 제외한 다른 CPU 의 캐시 메모리는 '무효' 가 되고, 다시 말해 마지막으로 수정한 CPU 의 캐시 메모리만 '유효'가 되고 나머지는 모두 '무효' 상태가 된다. ====== 프로세스 ====== 운영체제는 각 프로세스의 관리를 위해 프로세스 콘트롤 블록(PCB) 을 생성한다. ===== 리눅스 프로그램의 구조 ===== | 스택 세그먼트 | | 힙 | | 데이터 세그먼트 | | 텍스트 세그먼트 | | 이름 | 설명 | | 스택 세그먼트 | 함수를 실행할 때의 매개변수 또는 지역변수를 저장 | | 힙 | malloc 등으로 메모리를 동적으로 할당할 때 사용 | | 데이터 세그먼트 | 전역 변수를 저장 | | 텍스트 세그먼트 | 프로그램 코드를 저장 | ===== 리눅스에서의 프로세스 생성 ===== 부모 프로세스 FORK() : 자식 프로세스 생성(자신과 똑같은 프로세스를 복사) 부모 프로세스 EXEC() : 프로그램을 수행 - 부모 프로세스는 wait 를 호출하여 자식 프로세스가 종료될 때까지 기다린다. - 자식 프로세스 프로그램이 종료하면, 부모 프로세스는 기다림에서 깨어난다. ==== 프로세스가 생성되서 실행되기 까지 ==== - 프로세스가 생성되면 대기큐에 등록이 된다. - 운영체제 스케줄러에 의해 CPU 에게 실행이 된다. 도중에 인터럽트나 외부장치의 입력을 받아야 한다면, 잠시 준비큐로 옮겨진다. - 문맥전환(context switch) 이 일어나면서 다른 프로세스가 실행하게 된다. - 외부장치로 부터 입력을 받았다면, 준비큐에서 다시 대기큐에 등록되었다가 실행된다. ====== 프로세스 스케줄링 방식 ====== ===== FCFS (First-Come First-Served) ===== 가장 먼저 생성된 프로세스를 먼저 서비스(실행)하는 방식 ===== 라운드 로빈 ===== 여러 프로세스들이 CPU 를 조금씩 돌아가며 할당받아 실행되는 방식. 이때 프로세스들은 시간 할당량 동안 할당된다. ===== 우선 순위 ===== 우선 순위가 가장 높은 프로세스 부터 서비스(실행)되는 방식. 우선순위가 같은 경우에는 FCFS 방식을 적용한다. ====== 프로세스간 동기화 ====== 하나의 데이터를 여러개의 프로세스가 동시에 엑세스한다고 했을 때, 과연 어떤 방법으로 동기화를 시키는가? - 임계영역을 두고 동기화 하는 방법 - 피터슨 알고리즘 (ⓐ번 방법을 개조) - 세마포어 ====== 프로세스간 통신 ====== - 파이프를 이용한 통신 - 메세지큐를 이용한 통신 - 공유 메모리를 이용한 통신 ====== 메모리 관리 ====== | 가상메모리 | 메모리 공간보다 큰 프로그램을 실행하기 위하여 프로그램을 작은 단위로 쪼개서 실행시키는 방식 | | 페이지 | 프로그램을 일정한 크기로 쪼개는 단위 | | 페이징 | 페이지 단위로 메모리에 올리며 동작하는 것 | | 페이지 테이블 | 프로세스마다 각 페이지가 메인 메모리의 어느 곳에 저장되어 있는지를 알려주는 테이블. OS가 운영 | ===== 가상 주소로 실제주소 구하기 (페이지 프레임 시작주소 + 변위) ===== 가상 주소는 '페이지 번호, 변위' 로 이루어져 있다. 실제주소를 구하기 위해서는 '페이지 프레임 시작주소 + 변위' 를 하면 된다. ===== 다단계 페이징 ===== 가상 메모리의 크기가 커지면서, 페이지번호에 할당되는 비트수가 커지는 데, 이에 따른 메모리 낭비를 줄이기위해 사용한다. 다단계 페이지 가상주소는 '페이지 디렉토리 인덱스, 페이지 테이블 인덱스, 변위' 로 이루어져 있다. ===== 세그멘테이션 ===== 프로그램을 페이지단위로 쪼갤때, 이 중 일부는 텍스트 세그먼트, 데이터 세그먼트의 일부가 될 것이다. 페이징을 사용할 경우, 논리적으로 독립된 내용들이 구분되지 못하고 하나의 페이지로 묶여 동작하는 문제점이 생긴다. 논리적으로 독립된 의미의 세그먼트 단위로 동작하는 메모리 관리기법이다. | 디스크립터 테이블 | 각 세그먼트가 어느 영역에 저장되었는지와 크기 정보등을 운영체제가 테이블로 관리 | ===== 가상주소로 실제주소 구하기 (세그먼트 시작주소 + 변위) ===== 가상주소는 '세그먼트 번호, 변위' 로 이루어져 있다. 실제주소를 구하기 위해서는 '세그먼트 시작주소 + 변위' 를 하면 된다. ===== 단편화 문제 ===== 메모리 할당이 불연속적으로 일어나기 때문에 큰 크기의 메모리 공간은 줄고, 작은 크기의 빈 메모리 공간이 늘어남으로써 세그먼트가 들어갈 수 있는 공간이 없어지는 문제 ===== 단편화 문제의 해결책 ===== * 세그먼트를 작은 크기의 단위로 다시 나누어 동작하는 방법 (세그멘테이션 기법 + 페이징 기법) * GDTR(Global Descriptor Table Register), LDTR(Local Descriptor Table Register) : 디스크립터 테이블에 대한 위치정보 저장 ====== 파일 시스템 ====== NTFS 든, EXT2 든 각 파일 시스템의 동일한 방식은 어떤 데이터 파일이 디스크에 저장될 때, 최대한 계층화적으로 파일의 정보(시간, 용량, INODE NUMBER 등)를 저장한다는 것이다. 이렇게 하는 것은 나중에 검색시간의 단축을 위함이다. 마치 DNS 를 보는 듯 하다. ====== 네트워크 ====== TCP/IP 에 대한 설명은 아래의 그림 하나로 충분하다. {{ :computer:job:rtcclab:osi.gif |}} ---- {{indexmenu>:#1|skipns=/^(wiki|etc|diary|playground)$/ skipfile=/^(todays|about|guestbook)$/ nsort rsort}} ----