경제적, 정치적 결정을 내릴 때 시뮬레이션을 참고하는 경향은 오늘 날 점점 강화되고 있습니다. 현실에서 일어나는 과정을 컴퓨터에서 계산 하는 것인데 그 이유는 2가지가 있습니다.

 

 

첫째, 아직 일어난 적 없는 과정을 연구할 때 시뮬레이션이 쓰입니다. 날씨 예측이나 향후 100년 동안의 세계 기후 시뮬레이션들 일어나지 않은 과정들에 활용이 됩니다.

 

둘째, 현실에서 실험이 너무 번거롭거나 비용이 많이 들 때 시뮬레이션이 쓰입니다. 예컨데 현실에서자동차 충돌 실험을 하려면 매번 비싼 차체를 고철로 만들어야 합니다. 충돌 과정 전체를 컴퓨터에서 계산할 수 있다면 효율적으로 일을 해결할 수 있습니다.

 

하지만 위의 2가지 이유말고 의문점이 생깁니다. "여기서 말하는 시뮬레이션은 현실과 얼마나 유사할까?" 라는 질문을 할 수 있습니다. 왜냐하면 시뮬레이션은 엄연치 현실과는 오차범위가 있고 언제나 예외,변수등이 일어날 수 있습니다.

 

현실에서 마주치는 과정을 계산하려며 물리량들의 상호관계를 기술하는 '미분방정식'을 풀어야 합니다. 그런데 대개의 미분방정식 풀이는 완전한 해를 구하는 방식으로 이루어지지 않습니다. 대신에 사람들은 문제를 모든 점에서 고찰하지 않고 띄엄띄엄 떨어진 점들로 구성된 격자에서만 고찰함으로써 이산화 (discretize)합니다. 예를 들어 온도, 풍속 등을 모든 지점에서 계산하는 대신에 전체 지역을 1제곱 킬로미터 면적의 구역으로 나누고 각 구역에서의 값을 계산하는 것으로 만족해야 합니다.

 

일반적으로 그 격자가 촘촘할수록 미분방정식의 해는 현실과 더 유사하게 됩니다. 그러나 격자가 촘촘해지면 그만큼 계산에 공이 더 많이듭니다. 이를테면 3차원 공간에서 일어나는 한 현상을 시뮬레이션하는데, 격자의 눈의 한 변을 반으로 줄이면 계산에서 고려할 점들이 8배로 늘어나므로 계산 시간도 8배로 늘어나게 됩니다. 이 때문에 날씨 예측에서 격자를 점점 더 촘촘하게 만들다보면 내일 날씨의 계산 결과가 모래에야 나오는 상황이 발생할 수도 있습니다.

 

 

 

때로는 촘촘한 격자가 필요하지 않습니다. 예컨대 기체나 액체의 흐름을 고찰할 때는 그 흐름이 층류(laminar flow)여서 뒤엉킴 없이 매끄럽게 흐르기만 한다면 비교적 성긴 격자로도 좋은 계산 결과를얻을 수 있습니다. 반면에 난류(turbulent flow)에서는 아주 작은 소용돌이 하나도 흐름 전체에 중요한 영향을 미치므로 더 촘촘한 격자가 필요합니다.

 

이른바 '다중격자 알고리즘(multigrid algorithm)'의 원리는 1970년대 후반 이래로 개발되었습니다. 이 알고리즘은 고정된 격자를 사용하는 대신에 풀어야 할 미분 방정식을 고찰하여 어느 구역에서는 격자를 더 촘촘하게 만들어야 하고 어느 구역에서는 비교적 성긴 격자로도 충분한지 판단합니다. 이 알고리즘의 최대 장점은 계산의 복잡성을 줄여서 훨씬 더 빠른 계산을 가능케 하는 것에 있습니다.

 

다중격자 알고리즘은 최신 컴퓨터들의 계산 능력 향상에도 불구하고 그 능력을 아껴 쓰기 위한 노력이 앞으로도 늘 필요할 것임을 보여주는 한 사례입니다. 오늘날 사람들은 컴퓨터의 놀라운 성능을 대수롭지 않게 여기는 경우가 많습니다. 컴퓨터 내부에서 작동하는 알고리즘의 효율성을 높이기 위해서 수많은 노력과 인력이 들어갑니다.

 

 

#다중격자알고리즘 #multigridalgorithm

 

 

 

 

 

 

 

일찍이 기원전 300년경에 그리스 수학자 유클리드(Euclid)가 제시한 이 알고리즘은 두 개의 수의 최대 공약수를 구하는 절차입니다. 조금 더 구체적으로 표현하자면 유클리드 알고리즘은 반복 절차입니다. 이 말은 즉, 결과에 도달할 때까지 동일한 수학적 연산이 계속 반복되는 것입니다.

 


 

예제로 a=1513과 b=357의 최대공약수를 구해보겠습니다. 먼저, 큰 수를 작은 수로 나눌 때 나오는 나머지 r을 알아내야 합니다. 이 예제에서는 r은 85입니다.

 

 

 

1513= 4 * 357 + 85

이번에는 작은 수 b를 r₁으로 나눌 때 나오는 r₂를 구합니다.

357 = 4 * 85 + 17

이러한 작업을 계속 반복하게 됩니다. 항상 작은 수(이 단계에서는 r₁)를 나머지 (r₂)로 나누는데, 나눗셈의 나머지가 0이 될 때까지 이 작업을 반복하게 됩니다. 이 예에서는 벌써 다음 단계에서 나머지가 0을 가지게 됩니다.

85 = 5 * 17 + 0

17은 앞서 등장한 모든 나머지들의 약수이며 a와 b의 약수이기도 합니다. 정확히 말하자면 17은 a와 b의 최대공약수입니다.

유클리드 알고리즘은 두 수를 우선 소인수분해한 다음에 그 소인수들을 비교하는 방법보다 더 신속하고 깔끔하게 최대 공약수 구하기 문제를 해결할 수 있습니다. 게다가 유클리드 알고리즘은 정수가 아닌 수에도 적용할 수 있습니다. 임의의 수들의 "공통 단위"를 유클리드 알고리즘으로 구할 수 있습니다. 하지만 이 알고리즘이 항상 유한한 개수의 단계를 거쳐 최종 결과에 도달하는 것은 아닙니다. 1과 √2에 유클리드 알고리즘을 적용하면, 나머지들이 점점 더 작아지기는 하지만

나눗셈의 나머지가 0으로 되는 일은 끝내 일어나지 않을 것입니다. √2처럼 통약불가능한 수들이 존재한다는 깨달음은 온 세계를 자연수들의 비율로 기술할 수 있다는 피타고라스 추종자들의 세계관을 무너뜨렸습니다.

 


 

 

※ 오늘은 '유클리드 알고리즘'에 대하여 알아보았습니다.

이 포스트는 학부에서 제공하는 기본적인 강의와 컴퓨터 공학 책들을 토대로 알기 쉽게 내용을 작성하였습니다. 하지만 계속 더 유익하고 논문 및 전문 서적을 읽어가며 더 추가돼야 할 내용이 있으면 알고리즘 포스트와 콘텐츠들을 계속 고도화하는 방식으로 진행하려고 합니다.

 

 

 

4차 산업혁명 시대를 맞아 우리는 컴퓨터를 통해 활발하게 일상의 불편함을 해결하고 있습니다. 우리가 컴퓨터를 통해 문제를 해결한다는 것은 인간과 컴퓨터가 의사소통을 한다는 것을 의미합니다. 의사가 소통을 하는 데는 언어가 필요한데 컴퓨터와 인간이 사용하는 언어는 다르기 때문에 이를 번역해주는 컴파일러가 필요합니다. 이번 포스트에서는 컴파일러의 필요성에서 대해서 간략히 설명할 것입니다.

 

 

 

 

 

많은 사람들은 왜 컴파일러를 사용해야 하는지, 컴파일러가 무슨 일을 하는지 잘 모른 채 컴파일러를 사용해 개발을 하고 있습니다.

인간이 컴퓨터에게 일을 시키려면 컴퓨터와 인간이 서로 이해할 수 있는 공통적인 대화 수단이 필요합니다. 이러한 대화 수단을 언어(language)라고 하는데, 언어는 의사소통을 하는 대상이 누구냐에 따라 자연 언어(natural language)와 형식 언어(formal language)로 나뉘게 됩니다. 자연 언어는 한국어, 영어, 중국, 프랑스어, 일본어 등 인간과 인간이 의사소통을 하는 언어로서 지역이나 민족에 따라 자연 발생적으로 생성된 언어입니다.

반면에 형식 언어는 인간과 기계 사이에 의사소통을 하는 언어로서 인위적으로 만들어진 언어입니다. 이 포스트에서는 컴퓨터와 의사소통과 관련된 내용을 설명할 계획이므로 자연 언어보다는 형식언어에 관심을 중점을 둘 것입니다.

 

MIT교수이자 언어학자인 노암 촘스키

 

미국 언어학자이자 MIT 공대 교수인 노암 촘스키(Noam Chomsky)는 형식 언어를 4 가지로 분류했는데 그 종류와 관계는 아래의 그림과 같습니다.

 

형식 언어 중에서 컴퓨터와의 의사소통에 사용되는 언어를 '컴퓨터 언어' 혹은 '프로그래밍 언어(Programming language)'라고 합니다. 프로그래밍 언어는 현실 세계에 존재하는 어떤 문제를 풀기 위한 일련의 과정을 기술하는데 사용하는 것으로 사용 목적, 형태와 기능, 세대 등에 따라 여러 가지로 분류할 수 있습니다. 먼저 형태와 기능에 따라 저급 언어(Low-level langauge)와 고급 언어(High-level language)로 나뉩니다.

 

 

기계어 번역

 

 

저급언어에는 기계어(Machine language)와 어셈블리어(Assembly language) 등이 있습니다. 프로그래밍 언어 중에서 초기에 사용된 언어는 0과 1로 구성된 기계어였습니다. 초기에 기계어를 주로 사용한 이유는 컴퓨터가 0과 1로 만들어진 추상 기계(Abstract machine)이기 때문이었습니다. 그러나 기계어로 프로그래밍을 하는 것은 상당히 어렵고 매우 복잡하다는 단점이 있어 이를 보완하기 위해 나온 언어가 어셈블리어입니다.

어셈블리어는 0과 1로 구성된 기계어 대신 더하기에 ADD, 빼기에는 SUBT 등 대응하는 명령 기호를 사용함으로써 프로그래밍 작업에서 기계어의 단점을 조금 보완했습니다. 하지만 여기서 문제가 발생하게 됩니다. 인간이 어셈블리어를 사용하여 문제를 서술하고 나니 컴퓨터가 이것을 이해하지 못하였습니다. 이해할 수 있는 언어가 달랐기 때문입니다.

이를 쉽게 이해하기 위해 자연 언어를 빗대어 살펴보겠습니다. 예를 들어 프랑스어를 모르는 한국인과, 한국어를 모르는 프랑스인이 서로 만나 인사를 한다고 가정을 해보겠습니다. 서로 말을 알아듣지 못하니 통역사가 필요한데, 이러한 통역사는 아래의 그림과 같이 번역기(Translator)의 역할을 수행하게 됩니다. 앞서 언급한 어셈블리어를 기계어로 번역해주는 번역기는 어셈블러(Assembler)라고 합니다.

 

 

 

 

 

그러나 어셈블리어도 저급 언어의 수준을 벗어나지는 못했으며, 그 후 저급 언어의 단점을 보완하기 위해 C,파스칼,알골,포트란,코볼 등 사람 중심의 고급 언어가 나오게 되었습니다. 한편 고급 언어도 저급 언어와 마찬가지로 기계어를 변환해주는 번역기가 필요한데 이를 '컴파일러'라고 합니다.

컴파일러가 필요한 이유는 다음과 같이 정리할 수 있습니다.

인간은 문제를 해결하기 위해 컴퓨터를 사용하며 컴퓨터와 의사소통을 하는데 '언어'가 필요합니다. 컴퓨터는 기계어를 사용하지만 인간이 기계어를 사용하여 문제를 표현하기란 무척 어렵기 때문에 인간은 사람 중심 언어인 고급 언어를 사용합니다. 그런데 인간이 사용하는 고급 언어는 컴퓨터가 이해하지 못합니다. 따라서 인간이 사용하는 고급언어를 기계어로 변환해주는 컴파일러가 필요한 것입니다.

 


 

※ 오늘은 '컴파일러는 왜 필요할까?'에 대하여 알아보았습니다.

이 포스트는 학부에서 제공하는 기본적인 강의와 책들을 토대로 알기 쉽게 내용을 작성하였습니다. 하지만 계속 더 유익하고 논문 및 전문 서적을 읽어가며 더 추가돼야 할 내용이 있으면 컴파일러 포스트와 콘텐츠들을 계속 고도화하는 방식으로 진행하려고 합니다.

'컴퓨터공학 > 컴파일러' 카테고리의 다른 글

[컴파일러] 프리 프로세서  (0) 2019.09.29
[컴파일러] 어셈블러  (0) 2019.09.29
[컴파일러] 번역기의 종류  (0) 2019.09.29

+ Recent posts