이전글

http://www.inven.co.kr/board/powerbbs.php?come_idx=2097&iskin=lol&l=519190

------------------------------------

 

지난 글에서 우리는 컴퓨터 작동 원리의 가장 기본적인 것을 배웠습니다.

 

컴퓨터는 Gate라고 하는 소자로 만들어진 거대한 계산기이고,

 

이 계산기에는 덧셈기, 곱셈기와 같은 다양한 연산 회로가 들어가 있으며,

 

한편으로 레지스터와 같이 데이터를 저장하는 회로도 들어가 있습니다.

 

이번 글에서는

 

그렇다면 과연 컴퓨터 안에서

연산 회로데이터를 저장하는 회로가 어떻게 구성되어 있는지


그리고 우리가 컴퓨터를 실행시킬 때

컴퓨터가 어떻게 우리 명령을 수행하는 지에 대해 알아보도록 하겠습니다.

 

또한 이에 대한 이해를 바탕으로 GPU

더 나아가 병렬 컴퓨팅이란 어떤 것인가에 대해서도 다뤄보도록 하겠습니다.

 

----------------------------------

 

2. 컴퓨터 구조

 

2.1 폰 노이만 구조

 



20세기 초에 폰 노이만 이라고 하는 헝가리 출신 미국인 과학자가 있었습니다.


이 분은 대중에게는 잘 알려지진 않았는데,

수학, 물리학, 컴퓨터 공학, 통계학, 경제학 등등...

다양한 분야에서 업적을 세운, 지금으로 말하면 먼치킨급 천재였습니다.


(위키를 찾아보시면 폰 노이만에 대한 ㅎㄷㄷ한 일화들을 보실 수 있습니다)

(https://namu.wiki/w/%EC%A1%B4%20%ED%8F%B0%20%EB%85%B8%EC%9D%B4%EB%A7%8C#rfn-5)

 

이 분의 업적은 다양하지만, 그중 하나는

바로 폰 노이만 아키텍쳐를 고안한 것입니다.

현대 컴퓨터 구조는,

모두 폰 노이만 아키텍쳐를 따라서 만들었다고 해도 과언이 아닙니다.

 


 

폰 노이만 아키텍쳐

간단하게 말하자면


CPU메모리를 분리하고서


메모리에다가 명령어와 데이터 등등을 모두 집어 넣은다음


명령어를 순차적으로 읽어가면서 하나씩 수행하는 구조입니다.

 

명령어는 쉽게 비유하자면 우리가 쓰는 한글 프로그램 같은 거고

데이터는 한글 프로그램으로 작성된 한글 문서와 같은 게 되겠습니다.

 

어렵게 느껴지신다면 그냥 메모리 안에

명령어와 데이터가 함께 들어있다는 것만 기억하시면 됩니다.

 


1.2 메모리 계층구조

 

자 그러면 여기까지

컴퓨터가 연산장치메모리로 이루어져 있다는 것을 배웠습니다.

 

그리고 지난번 글에서 우리는

연산장치메모리는 모두 Gate를 이용해서 구현할 수 있다는 것을 배웠습니다.

 

그러면 Gate 소자만 많이 있으면 우리가 쓰는 컴퓨터를 만들 수 있겠죠? ㅎㅎ

이랬으면 좋겠지만...


아쉽게도 Gate 소자로 만든 메모리에는 단점이 있습니다.

바로 단가가 비싸고, 크게 만들기 어렵다는 사실입니다 ㅠㅠ

 

그래서 Gate 소자 만으로

우리가 사용하는 한글 프로그램이나, 문서 파일, 음악, 동영상 파일 등등을 저장하려면

아주 아주 돈이 많이 들어갑니다.

 

그래서 컴퓨터 공학자 들은 Gate 소자를 대체하여


단가도 비교적 싸고, 크게 만들기도 쉬운

D-RAM(Dynamic RAM) 이라는 저장장치를 이용하기 시작했습니다.

 


 

D-RAMRAM이라는 저장장치의 한 종류로

일반적으로 RAM을 말한다면 보통 이 D-RAM을 말하는 경우가 많습니다.

 

RAM(Random Access Memory)

쉽게 말해서 저장 장치가 여러 구역로 나뉘어 있는데,


각 구역에는 고유의 주소 값이 지정되어 있고,

RAM의 사용자가 전선을 통해서 주소 값에 대한 이진수 신호를 입력하면

주소에 있는 데이터를 출력해주는 장치입니다.

 

예를 들어서

RAM0001 번째 저장 공간에는 00010001 이라는 데이터가 저장되어 있고,

0002 번째 저장 공간에는 10101010 이라는 데이터가 저장되어 있고,

0003 번째 저장 공간에는 11100011 이라는 데이터가 저장되어 있고, 이런 식인데

 

사용자가 RAM에게 “0002번째 저장 공간에 있는 데이터를 가져다줘!” 하고 요청하면

RAM10101010이라는 데이터를 출력해주는 형식입니다.

 

그런데 레지스터 대신 D-RAM을 사용하면

모든 문제가 해결되느냐 하면

또 그것도 아닙니다.

 

D-RAM은 상대적으로 싸고, 크게 만들기도 쉽지만,

데이터를 전송하는 속도가 레지스터에 비해 무지하게 느립니다.

그래서 D-RAM 만을 사용하면 컴퓨터가 무지 느려지겠죠.

 

그래서 공학자들은

S-RAM 이라고 하는 장치를 사용하기 시작하였습니다.

S-RAM 이라고 하는 장치는 RAM의 한 종류인데,

다른 말로는 캐시 메모리 라고도 합니다.

 

그러나 S-RAM은 역시 레지스터와 비슷하게

비싸고, 대용량으로 만들지는 못합니다.

 

그래서 공학자들은 S-RAM을 작게 만드는 대신

사람들이 잘 안 사용하는 데이터D-RAM에 저장해 놓고

사람들이 자주 사용하는 중요한 데이터 들은 S-RAM에 저장을 하기 시작했습니다.

 

결과적으로 컴퓨터는 다양한 종류의 메모리를 이용하는데,

 

레지스터에는 당장 계산을 하고 있는 내용을 기억하는데 쓰고,


S-RAM에는 자주 찾아서 쓰는 데이터를 저장하는 데 쓰고,


D-RAM에는 현재 실행 중인 모든 프로그램과 데이터에 대한 정보를 저장하는데 씁니다.

 

또한 아시다시피 컴퓨터는 SSDHDD 같은 보조 기억장치를 이용하기도 합니다.

 

이렇게 메모리들은 계층 별로 나눈 것을

메모리 계층 구조라고 말합니다.

 

 

1.3 연산 장치와 명령어 수행 과정

 

자 지금까지 폰 노이만 아키텍쳐에서 메모리에 대해 알아봤으니

이제는 연산 장치에 대해 알아볼 차례입니다.

 

지난번 글에서도 말씀드렸듯이

여기서 연산 장치란 것은 Gate로 이루어진 계산회로의 집합을 말합니다.


따라서 CPU에다가 적절한 입력을 주면

CPU는 그 입력 값에 따라서 다시 적절한 출력을 내보내지요.

 

다만 CPU는 다양한 종류의 연산을 수행하기 때문에,

CPU에게는 어떤 연산을 수행해야 하는지를 알려줘야 합니다.


예를 들어 덧셈을 하고 싶다면

CPU에게 덧셈을 하라는 명령어를 입력해주어야 합니다.

 

그런데 위에서도 나와 있듯이,

현대 컴퓨터는 대부분 폰 노이만 아키텍쳐로 이루어져 있습니다.

 

따라서 이러한 명령어들은 모두 메모리에 저장되어 있으며,

메모리에 저장되어야 하므로 당연히 데이터처럼 01의 형식으로 이루어져 있습니다.

이렇게 01의 형식으로 이루어진 명령어를 기계어(machine language)라고 합니다.

 

CPU메모리에서 명령어들을 읽고,

그에 따른 연산을 수행하게 되는데요.


그렇다면 이 다음으로는

연산 장치가 어떤 방식으로 명령어를 수행하는지 알아보도록 하겠습니다.

 


위의 그림은 폰 노이만 아키텍쳐에서 메모리연산 장치를 도식화한 것입니다.

 

연산장치메모리에서 명령어를 읽어오게 되는데,

읽어온 명령어를 가지고 레지스터에 저장된 데이터를 연산에 이용하게 됩니다.


예를 들어서 레지스터에 기록된 AB라는 값을 더하라는 명령어가 있다면

레지스터에서 AB의 값을 가져와서 덧셈을 실행하게 되는 것입니다.

 

다만 여기서 연산 장치

명령어를 보고서

어떤 연산을 수행해야 할지 결정하는 능력이 부족하기 때문에


별도로 제어 장치를 따로 두게 되는데요.


제어 장치는 주어진 명령어를 해석한 다음,

어떤 명령어를 수행해야 하는지 연산 장치에게 알려주는 역할을 하게 합니다.

 

물론 제어장치 또한 연산장치처럼 Gate 소자로 이루어진 계산 회로입니다.

다만 연산장치와는 다르게 명령어를 해석하는 능력에 특화된 것이지요.

 


연산 장치가 명령어를 읽어오는 과정은

명령어의 종류마다 다르고

또 컴퓨터마다 조금씩 다르기는 하지만,

 

보통 다음 5단계의 과정을 거치게 됩니다.

 

1. Instruction Fetch : 메모리에서 명령어(Instruction)을 읽어옵니다.

2. Instruction decode/Register read : 명령을 해석하고, 필요한 경우 레지스터에서 값을 읽어옵니다.

3. Execution operation : 실제로 연산을 수행합니다.

4. Memory Access : 필요한 경우 메모리에서 데이터를 읽어오거나, 데이터를 메모리에 저장합니다. (일부 명령어에서 사용)

5. Write back : 최종적인 결과 값을 레지스터에 저장하여 기억합니다.

 

어려우시면 그냥 건너 뛰셔도 상관없고요.


쉽게 생각하면 마트에서 물건을 사는 비유로 생각해볼 수 있습니다.

 

마트에 가기 전에 우리가 사야 될 물건들의 리스트가 있는데,

우리는 그 리스트를 보고서 하나씩 물건들을 장바구니에 담게 되지요?

 

CPU도 자신이 해야 할 일들이 메모리에 저장되어 있는데,

그걸 하나씩 수행해 가면서 연산을 처리하고

그 결과 값을 레지스터나 다른 메모리에 기억을 해두게 되는 것입니다.


 

1.4 병렬 컴퓨팅




그러면 여기까지 CPU가 어떻게 돌아가는지 대충 알아봤으니,

이제 병렬 컴퓨팅이 무엇인지 알아보겠습니다.

 

컴퓨터에 대해 별로 관심이 없는 분들이라도

CPU듀얼코어이니 쿼드코어이니 하는 것을 들어보셨을 것입니다.

 

여기서 코어라는 것은 한 묶음의 연산 장치를 말하는 것으로,

각각의 코어는 데이터를 읽고, 연산을 수행하는 일련의 과정을 수행할 수 있습니다.


쉽게 생각하면, 하나의 칩 안에 CPU가 여러 개가 들어가는 것과 비슷하죠.

 

사실 엄밀한 의미에서 병렬 컴퓨팅은 여러 종류가 있습니다.

넓은 의미에서 병렬 컴퓨팅은 여러 가지 일을 동시에 해내는 것을 말합니다.

 

그러나 그걸 일일이 다 설명하면 재미도 없고 머리만 아프기 때문에,


우리는 좁은 의미의 병렬 컴퓨팅

멀티코어 프로세서에 의한 병렬 컴퓨팅에 대해 다루도록 하겠습니다.

 

프로세서란 컴퓨터에서 프로그램을 실행시키는 주체를 말합니다.

즉 위의 예제처럼 CPU 생각하시면 됩니다.


멀티코어 프로세서
즉, 프로세서인데 코어가 여러개인 프로세서를 말하는 거죠.
위에서 본 듀얼코어 CPU, 쿼드코어 CPU 등이 여기에 해당됩니다.

물론 컴퓨터를 여러 대를 사와서

컴퓨터들을 서로 네트워크로 연결한 다음

한 가지 일을 처리하도록 하는 것도 멀티코어 프로세서라 할 수 있습니다.

(요즘 나오는 슈퍼 컴퓨터의 원리가 이렇죠)

 

멀티코어 프로세서를 쉽게 비유해서 생각해보면


사야할 물건들이 적힌 하나의 리스트를 가지고

친구 4명이서 물건을 사러 마트에 온 상황을 생각하시면 됩니다.

 

사야할 물건 리스트를 보고서

 

친구 A는 사과를 사러 다녀오고,

친구 B는 그 다음에 적힌 우유를 사러 다녀오고,

친구 C는 그 다음에 적힌 라면을 사러 다녀오고 이런 식인거죠.

 

친구들 끼리 해야할 일을 나눠서 하니까

당연히 일들을 더 빠르게 처리할 수가 있게 되겠죠.



1.5 병렬 컴퓨팅의 한계?

 

최근에 기사를 보면


알파고를 돌리기 위해서

cpu1202, gpu176개가 들어갔다고 합니다.

 

그런데 구글 딥마인드 대표님의 설명을 들어보면

원래는 알파고를 돌리기 위해 cpu를 약 1800개 가량 사용했다고 합니다.

그런나 cpu 수를 늘려도 성능이 좋아지지 않아서

최적의 성능을 낼 수 있는 cpu 개수를 찾았고, 그게 1202개였다고 합니다.

 

그냥 단순히 생각하면

cpu 개수가 늘어난다는 것은 연산을 할 수 있는 장치 개수가 늘어나는 건데

그러면 cpu 개수가 늘어날수록 더 성능이 좋아지는 게 아닌가?

하고 생각해볼 수 있습니다.

 

그러나 아쉽게도 병렬 컴퓨팅에는 여러 가지 함정이 있습니다.

 

아까 4명의 친구들이 마트에 물건을 사러 나온 상황을 통해

병렬 컴퓨팅이 가진 문제점을 알아보도록 하겠습니다.

 

병렬 컴퓨팅이 가진 문제점은

크게 세 가지 정도가 있습니다.

 

첫 번째는 작업 분배 문제입니다.

 

친구들이 물건을 사러 나왔지만,

목록에 적힌 물건을 사는 난이도는 서로 다를 수가 있습니다.

 

예를 들어

A라는 친구는 달걀을 사오라는 명령어를 보고서

빨리 가서 쉽게 달걀을 가져왔는데,

B라는 친구는 TV를 사오라는 명령어를 보고서

낑낑대면서 어렵게 TV를 가져오는 겁니다.

 

그러면 B라는 친구가 TV를 가져오는 동안

A라는 친구는 아무것도 하는 게 없이 그냥 놀게 됩니다.

 

이렇게 노는 친구가 생기기 때문에

코어가 많아져도 성능이 좋아지지 않을 수 있습니다.

 

두 번째는 명령어들의 연관성 문제입니다.

 

예를 들어 마트에서 그날 그날에 따라

임의로 소고기나 돼지고기 중 하나를 할인하는데

 

어쩌다보니 사야할 품목 목록에

소고기나 돼지고기 중에 할인하고 있는 고기를 사오라는 명령이 적혀있다고 해봅시다.

 

이 목록을 보고서 A라는 친구가 고기를 사러 고기 코너에 갔습니다.

그리고 다음 목록을 보고서 BC도 각각 물건을 사러 갔습니다.

 

그런데 D가 다음에 할 일을 봤더니

앞에 적힌 고기에 어울리는 소스를 사오는 명령이 적혀있는 겁니다.

그런데 마트에는 소고기 소스와 돼지고기 소스가 있어서

소스를 사기 위해서는 A가 무슨 고기를 사왔는지 알아야 합니다.

 

이 경우에 DA가 돌아올 때 까지 기다릴 수 밖에 없습니다.

 

이렇게 명령어 사이에 연관성이 있는 경우

이전의 명령이 끝나기 까지 기다려야 하므로,

코어가 늘어나도 성능은 그대로 일 수 있습니다.

 

세 번째로 데이터 쓰기 문제가 있습니다.

 

4명의 친구가 하나의 장바구니를 공유하고 있다고 해봅시다.

 

그런데 A라는 친구가 목록에 적힌 명령어를 처리하는 도중

수박을 장바구니에 넣어놨다고 해봅시다.

 

그런데 그 다음에 B라는 친구가 큰 락스통을 사왔는데

장바구니에 넣으려고 봤더니 장바구니가 꽉 차있는 겁니다.

 

이 경우에 B라는 친구는 A가 다시 수박을 꺼내기 전까지는

락스통을 장바구니에 넣을 수 없는 상황에 처하게 됩니다.

 

물론 사람의 경우에는 A가 수박을 꺼내는 동안 다른 일을 할수도 있지만

컴퓨터에서 코어는 모든 일을 순차적으로 수행해야 하므로

A가 수박을 꺼내는 동안 아무 일도 못하게 되버립니다.

 

위와 같은 이유들로 인해

cpu의 숫자가 늘어난다고 하더라도

성능이 좋아지지는 않는 상황이 발생할 수 있습니다.

 

이런 문제들을 해결하기 위해

공학자들이 엄청난 노력을 기울이고 있죠.

 

구글이 CPU 1202개를 이용하여

알파고를 실행시켰다고 하는데,

 

사실은 그 자체만으로도 엄청난 노력과 수고의 결과인 것입니다.

 


1.5 GPU

 



마지막으로 병렬 컴퓨팅을 이용하는 장치인,

GPU가 어떻게 돌아가는 것인지 알아보도록 하겠습니다.

 

GPU가 그래픽 연산을 담당한다고 알려져 있지만,

실제로는 GPU는 그래픽 뿐만이 아니라

다른 연산을 하는 데도 쓰일 수 있습니다.

 

GPU가 그래픽 연산에 특화되었다고 하는 이유는

바로 GPU에는

CPU에 있는 것 같은 연산장치들이 수없이 많이 들어있기 때문입니다.

하나의 GPU 안에는 연산장치가 수백개씩 들어가 있다고 보시면 됩니다.


위의 그림에서 ALU라고 적혀있는게 연산장치인데

CPU와 비교해 볼 때, 차원이 다르게 많이 들어있죠.

 

다만 GPU의 연산장치는 CPU 연산장치와는 다르게,

단순한 연산만을 처리하도록 설계되어 있습니다.

단순 반복 작업만 할 수 있는 것이지요.

 

비유를 하자면 GPU는 공장과도 같습니다.

CPU에서 어떤 많은 수의 연산이 필요할 때

CPUGPU에게 해야할 일들의 목록을 정리해서 넘겨주는 것입니다.

 

그러면 GPUCPU로부터 발주를 받고서

GPU 내부의 연산장치들에게 일들을 시킵니다.

그러면 그 결과를 받아서 다시 CPU에게 넘겨주는 것이지요.

 

GPU의 장점은

아까 위에서 말했던 병렬 컴퓨팅의 문제를

상당 부분 해결했다는 점에 있습니다.

 

우선 작업 분배 문제의 경우,

GPU의 연산장치 들은 서로 비슷비슷한 수준의 일을 하는 데다가,


한번 CPU로부터 발주를 받을 때

해야할 연산들을 대량으로 받기 때문에,


각각의 연산장치들에게 연산들을 분배해주기 쉽습니다.

 

두 번째로 명령어들의 연관성 문제의 경우,

GPU에 들어오는 연산들은

대부분이 명령어간에 서로 연관성이 없는,

다시 말하면 그냥 단순한 연산이기 때문에


한 명령어가 끝날 때까지 기다려야할 필요가 없어집니다.

 

마지막으로 데이터 쓰기 문제의 경우,

애초에 GPU는 데이터를 읽고 쓰는 연산을 별로 많이 하지 않기 때문에,

쉽게 말하면, 그냥 데이터 쓰는 것 없이 계산만 하면 되기 때문에,

데이터 쓰기 문제가 줄어들게 됩니다.

 

따라서 GPU

CPU에 비해 단순한 연산을 한번에 많이 할 수 있기 때문에

단순한 연산이 대부분인 그래픽 연산 등에 많이 이용됩니다.

 

또한 이번에 언론에 알려진

딥러닝 기반 알고리즘의 경우에는,

그래픽 연산과 비슷하게

단순한 연산들을 수없이 많이 반복하게 됩니다.

 

따라서 이론적으로는

딥 러닝에서 CPU를 쓸 때보다 GPU를 쓸 때,

컴퓨터에게 트레이닝을 시키는 시간이 줄어들게 됩니다.

, 더 빠르게 학습을 할 수 있다는 뜻이지요.

 

-------------------------------------------
여기까지 우리는 컴퓨터 구조에 대해 알아봤습니다.

현대 컴퓨터는 폰 노이만 아키텍쳐인데,
이는 연산 장치메모리가 분리되어 있고,
메모리에는 명령어데이터가 들어있는 구조를 말합니다.

또한 메모리연산 장치가 컴퓨터 안에서 어떻게 구성되있는지 확인했습니다.

덧붙여 병렬 컴퓨터GPU란 어떤 것인가에 대해 알아보았습니다.

그렇다면 다음 글에서는

하드웨어 측면에서 벗어나 소프트웨어 측면에서
프로그램들이 어떻게 돌아가는지,

그리고 프로그램을 어떻게 만드는 것인지

그리고 알파고는 어떻게 만들어 진 것인지에 대해 다뤄보도록 하겠습니다.


부족한 글 읽어주셔서 감사하고
질문과 의견은 언제든지 환영합니다 ㅎㅎ

다음글