'캐쉬'에 해당되는 글 2건

  1. 2010.03.24 메모리 계층(Memory Hierarchy)
  2. 2010.02.08 시스템 프로그래밍(System Programming)의 시작 (2)

메모리 종류 :

1. 메인(Main) 메모리 : 램(RAM) (D램)

2. 레지스터(Register) : CPU 안에 내장되어 있어서 연산을 위한 저장소 제공

3. 캐쉬(Cache) : S램.  CPU와 램사이에서 중간 저장소 역할

4. 하드디스크(Hard Disk)와 이외 장치 : 하드 디스크, I/O 장치 등등



메모리 계층 구조(Memory Hierarchy) :


메모리들은 프로그램이 실행하는 동안 데이터의 입력 및 출력을 담당한다.

메모리들의 차이는 CPU 와의 거리에서 온다.

CPU와의 거리가 가까울수록 빠르고 용량이 작으며 멀수록 느리고 용량이 크다.(기술과 돈의 문제)

하드디스크에 있는 내용은 프로그램의 실행을 위해 메인 메모리로 이동한다.

메인 메모리에 있는 일부 데이터도 실행을 위해 L2 캐시로 이동한다.

L2 캐시에 있는 데이터 일부는 L1 캐시로 이동한다.

L1 캐시에 있는 데이터중 연산에 필요한 데이터는 레지스터로 이동한다.


반대로 연산에 필요한 데이터가 레지스터에 없으면 L1 캐시를 살펴본다. 없으면 L2캐시 없으면 메인 메모리,

그래도 없으면 하드디스크를 참조한다. 하드디스크에서 데이터를 찾은 후 다시 메인 메모리 L2 캐쉬 L1 캐시를 거쳐

레지스터로 데이터가 들어오게 되는데 이경우 극심한 속도저하가 발생한다.

(참고 :

캐시를 없애 중간단계를 줄이는 것이 속도가 빠르지 않냐 생각할수 있는데
L1 캐시와 L2 캐시에, 연산에 필요한 데이터가 존재할 확률이 90% 이상이다.따라서 캐시는 속도향상에 도움을 준다)



L1 캐시와 L2 캐시 :

시스템의 성능을 좌우하는 클럭속도는 느린쪽에 맞춰진다.

CPU는 고속화되었지만 메인 메모리의 처리속도는 이를 따라가지 못한다.

CPU가 연산을 하기 위해선 데이터를 가지고 와서 연산을 한 후 연산결과를 메모리에 저장한 후에

다음작업을 수행할 수 있다.

따라서 아무리 CPU가 빠르게 연산을 수행한다 하더라도 데이터를 가지오고 저장하는 작업이 느리다면

전체적인 처리속도는 결코 빠를수 없다.

L1캐시는 이러한 레지스터와 메인 메모리간의 속도차이에 의한 성능저하를 막기 위해

메인 메모리의 저장된 데이터 중 자주 접근하는 데이터를 저장한다.

L1 캐시는 CPU 내부에 존재하므로 L1 캐시에서 데이터를 참조할 경우 속도저하는 발생하지 않는다.

하지만 여전히 L1 캐시는 메인 메모리의 모든 데이터를 저장할 수 없기에 L1 캐시에 없는 데이터를

CPU가 요구할 경우 속도의 저하로 이어진다.

따라서 캐시를 하나 더둔다.(L1 캐시에 용량을 증가시키는데ㄷ에도 한계가 있다(돈과 기술))

L2 캐시까지 존재함으로써 메인 메모리에 대한 접근은 더욱 줄어든다.

따라서 병목현상은 L1캐시와 메인 메모리에서 L2 캐시와 메인 메모리로 발생지역이 옮겨지게 된다.



캐쉬(Cache)와 캐쉬 알고리즘 :

템퍼럴 로컬리티(Temporal Locality) : 한번 접근이 이뤄진 주소의 메모리 영역은 자주 접근한다.

스페이셜 로컬리티(Spatial Locality) : 접근하는 메모리 영역은 이미 접근이 이루어진 영역의 근처일 확률이 높다.

캐시 프렌드리 코드(Cache Friendly Code) : 템퍼럴 로컬리티와 스페이셜 로컬리티를 최대한 활용하여
                                                             캐시의 도움을 받을수 있도록 구현한 코드



캐시 알고리즘 :


캐시 힛(Cache Hit) : 연산에 필요한 데이터가 L1 캐시에 존재할 경우


캐시 미스(Cache Miss) : 연산에 필요한 데이터가 L1 캐시에 존재 하지 않을 경우
(참고 : 이경우 L2 캐시를 검사하며 L2 캐시 미스가 발생하면 메인 메모리에서 데이터를 가져온다)


데이터의 이동은 블록 단위로 진행하여 스페이셜 로컬리티의 특성을 성능향상에 활용한다.
(예 : 0x10000 번지의 데이터를 요청하면 0x10000을 포함한 블록 전체가 전송된다)

(참고 : 현재 L2 캐시는 CPU 내부에 존재한다)

메모리 계층 아래로 갈수록 전송되는 블록 크기가 커진다.

아래에 존재하는 메모리에 대한 접근 횟수를 줄여준다.


캐시 교체 정책(Cache's Replacement Policy) :

프로그램이 실행된느 동안 모든 메모리는 항상 채워져 있다.

메모리가 꽉 채워져 있어요 요구하는 데이터를 가지고 있을 확률이 높아지기 때문이다.

이때문에 가지고 있지 않은 데이터를 요구할 경우 메모리가 꽉 찾기 때문에 메모리 블록을 교체해야 한다.

블록 교체 알고리즘은 캐시 교체 정책에 의해 달라진다.
(참고 :

대표적 블록 교체 알고리즘 :
LRU(Least-Recently Used) : 가장 오래 전에 참조된 블록을 밀어내는 알고리즘)

'Windows > _System Programming' 카테고리의 다른 글

StackBasedOverflows-Windows-Part1 (기본 개념)  (2) 2011.06.07
메모리 컨트롤  (0) 2010.03.24
메모리 계층(Memory Hierarchy)  (0) 2010.03.24
MMF(Memory Mapped File)  (0) 2010.03.12
라이브러리(Library)  (0) 2010.03.11
비동기 I/O 와 APC  (0) 2010.03.08
Posted by Dakuo

시스템 프로그램(System Program)

: 컴퓨터 시스템을 동작시키거나 하드웨어를 사용할 수 있도록 도와주는 프로그램



1. 컴퓨터 시스템의 주요 구성요소(Main Components)

컴퓨터 구조(Computer Architecture) : CPU <-> 캐쉬(Cache)
                                     
                                           ↕

운영체제(Operating System) : 메인 메모리(Main Memory) <-> 하드디스크(Hard Disk)



2. 컴퓨터 구조 :


1) CPU : 중앙처리장치(Central Processing Unit)

ALU(Arithmetic Logic Unit) : CPU 내부에 실제 연산을 담당하는 부분. 산술연산(+, -)과 논리연산(AND, OR)을 수행

컨트롤 유닛(Control Unit) : CPU 내부로 들어온 명령어를 해석해서 ALU 에게 전달한다.

레지스터(Register Set) : CPU 내부에 임시적으로 데이터(2진 데이터 : Binary Data, CPU에 따라 16, 32, 64 비트
저장가능)를 저장하기 위한 메모리 공간

버스 인터페이스(Bus Interface) : CPU 내에 I/O 버스의 통신 프로토콜(Protocol)을 이해하고 있는 장치

클럭 신호(Clock Pulse) : 클럭발생기에 의해 발생되며 이 신호에 맞춰 CPU를 구성하는 요소들이 일을 한다. 

(추가  : 클럭신호의 필요성(동기화)


위와 같은 그림에서 만약 클럭 신호가 없다고 가정하고 각각의 작동의 속도가 다르다고 가정하자.

예상 작동 : input 1에서 1, input 2에서 2의 숫자가 입력됬다. +연산장치가 연산을 해서 버퍼에 넘기고 출력장치가 버퍼에 있는 값을 읽어 3이라는 값을 출력했다

실제 작동 : input 1에서 1, input 2에서 2의 숫자가 입력됬다. 하지만 +연산을 하기도 전에 출력장치가 버퍼(Buffer)에 있는 쓰레기 값을 읽어 출력해버렸다.

여기서 + 연산의 속도와 출력장치가 버퍼를 읽는 속도의 차이 때문에 정상적으로 작동을 하지 못했다.
즉 장치마다의 속도차이가 존재하기에 동기화가 필요한것이다.
따라서 속도가 느린 장치에 맞춰 일을 시키면 정상적으로 작동을 할것이다.

동기화 작동 : input 1에서 1, input 2에서 숫자가 입력됬다. 클럭신호를 + 연산장치에 맞춰놓아서 +연산이 될때 출력장치가 버퍼의 3을 읽어와 출력을 한다)


2) 메인 메모리(Main Memory)

컴파일이 완료된 프로그램 코드가 올라가서 실행되는 영역


3) 입 · 출력 버스(Input / Output Bus)

컴퓨터를 구성하는 요소 사이에서 데이터를 주고 받기 위해 사용되는 경로이다.

버스 시스템(Bus System)은 데이터 종류에 따라

1. 데이터 버스(Data Bus) : 데이터를 이동하기 위한 버스(명령어, 피연산자 등)

2. 어드레스 버스(Address Bus) : 주소값을 이동하기 위한 버스

3. 컨트롤 버스(Control Bus) : 명령을 주고 받는 버스

예)

CPU : "데이터 보내"                              // 컨트롤 버스
Memory : "몇번지에 있는 데이터?"          // 컨트롤 버스
CPU : "0x000012"번지                            // 어드레스 버스
Memory : "20"                                      // 데이터 버스



3. 프로그램 실행 과정

1단계 : 전처리기 -> 컴파일러 -> 어셈블러 -> 링커 -> 실행파일

2단계 : 실행파일 -> 로드 -> 메모리

3단계 : 메모리 -> Fetch -> Decode -> Execution


1단계(실행파일 작성) :

1. 전처리기 : '#'으로 시작하는 지시자의 지시에 따라서 소스코드를 변경한다.
                   (참고 : #pragma지시자 는 - #이 붙어있어서 전처리 명령처럼 보이지만 컴파일러 지시자이다)

2. 컴파일러 : C 언어 등으로 구성된 전처리기를 거친 소스코드를 어셈블리 코드로 번역한다

3. 어셈블러 : 어셈블리 코드를 CPU가 이해할수 있는 바이너리 코드로 바꾸어 준다.

(참고 : 바이너리 코드(Binary)와 어셈블리 코드(Assembly)

CPU를 디자인하는 개발자가 만약 덧셈 명령어를 1111 이라고 정했다고 치자. 만약 1+2를 시킨다면
0001 1111 0010  이런 코드(바이너리 코드)를 구성해야 하는데 이것은 매우 알아보기 힘들다.

따라서 이걸 사람이 좀더 보기 쉽게

1111 를 ADD 로 하기로 하고 표를 만들어 둔다. 이제 소스를 작성할때 1+2를 시킨다면
0001 ADD 0010 이런식으로 작성하면 된다.(한결 보기 쉬울것이다) 이것이 어셈코드이다.

어셈블러는 이런 표를 참조해 ADD -> 0011 로 바꾸는 작업을 하는 프로그램이다)


4. 링커 : 프로그램 내에서 참조하는 함수나 라이브러리들을 하나로 묶고 연결시켜주는 작업을 한다.
(1단계를 마치면 실행파일이 생성된다. (바이너리 코드로 구성되있다))


2단계(실행파일 실행) :

실행파일을 실행시키면 메모리에서 로드(Load)를 해서 이 실행파일의 코드(바이너리 코드)들이 메모리에 저장된다.


3단계(실제 작동) :

1. Fetch : 메모리상에 존재하는 명령어를 CPU로 가져 오는 작업이다.(레지스터에 일단 저장한다)

2. Decode : 가져다 놓은 명령어를 CPU가 해석하는 단계이다.(컨트롤 유닛에서 수행한다)

3. Execution : 해석된 명령어대로 CPU가 실행한다.(ALU에서 수행한다)

Posted by Dakuo