아우스터리츠 전쟁

 

1805년 겨울에 프랑스의 나폴레옹의 군대는 아우스터리츠(Austerlitz, 현재는 체코의 남동쪽에 위치한 지역)라는 곳에서 오스트리아와 러시아 연합군과 대치하고 전투가 임박한 상태였습니다. 당시에 나폴레옹은 자신의 병력이 연합군보다 약 2만 명이 적은 상황에서, 연합군이 나폴레옹 군대의 옆쪽으로 공격하도록 유도한 후에, 연합군의 중앙을 공격하였습니다.

 

두개의 무리로 나누어진 연합군은 당황하여 도망가느라 바뻤고 나폴레옹의 군대는 각각의 남은 무리들을 공격하여서 대승을 거두었습니다. 약 3주후에 오스트리아는 나폴레옹과 조약을 맺고 프랑스에게 많은 땅을 내줌과 동시에 거액의 전쟁 보상금또한 지불하였다고 합니다.

 


 

 

 

2016년 미국 대통령 선거에서 승리한 도널드 트럼프 대통령또한 부통령인 마이클 펜스와 함께 분할 정복 전략으로 단기간에 많은 선거 유세를 소화하여 미국의 45번째 대통령이 되었습니다.

 


 

긴 글 읽어주셔서 감사합니다.

오일러(Leonhard Euler, 1707~1783)는 스위스의 수학자, 물리학자, 천문학자, 논리학자, 공학자로서 그래프의 창시자라고도 알려져 있습니다.

 


 

 

특히나 오일러의 등식들은 수학의 아름다움(?)을 표현하는 식으로 유명하게 알려져 있습니다. 이 식을 잘 살펴보면 영역이 다른 다섯 가지 수인 0,1(상수/constant), 자연상수 e (해석학), 원주율 π, 그리고 허수 i (대수학)가 모두 하나의 식에 포함되어 있으며, 수학의 가장 기초가 되는 4가지 연산인 곱셈, 지수, 그리고 등호가 모두 쓰인 책이기 때문입니다. 아인슈타인과 함께 20세기의 최고 물리학자로 불리는 리처드 파인만(Richard Feynman)은 이 식을 "수학에서 가장 비범한 식(the most remarkable formula in mathematics)"이라며 극찬하였습니다.

 


 

 

한편 1735년 프러시아의 쾌니히스베르크(현재는 러시아의 칼리닌그라드)에 위치한 프레겔 강 한가운데 섬 2개에 놓은 7개 다리가 있는데 주민들이 오일러에게 이 다리들을 빠짐없이 1번씩만 지나서 출발점으로 돌아올 수 있는지 물어보았습니다. 오일러는 그렇게 할 수 없다는 답변을 전달해 주었는데, 이 문제가 최초의 그래프 문제로 알려져 있습니다.

 

이 문제는 한 붓 그리기와 같은 문제이고, 오일러는 다리(그래프의 간선)를 한 번씩만 지나서 출발점으로 되돌아오려면 각 정점의 차수가 짝수여야 한다는 것을 증명하였습니다. 주어진 그래프에서 임의의 정점에서 출발하여 모든 간선을 빠짐없이 한 번씩만 지나면서 출발점으로 돌아오는 경로를 오일러 서킷(Euler Circuit) 또는 오일러 사이클이라고 합니다.

 

최근에 4차 산업혁명을 필두로 클라우드, 빅데이터, 인공지능, 사물인터넷(I0T), 핀테크, 스마트 팩토리&팜, AR&VR 등을 필두로 최첨단 기술들이 등장하였습니다.

그중에서도 사물인터넷에 대해서 설명하려고 합니다. 왜 대기업 및 IT기업에서는 사물인터넷(IoT)을 미래 먹거리 산업으로 삼았으며, 어떻게 우리 실생활에 적용이 되고 도움이 되는지 또한 알아보겠습니다.

 


※ 먼저 IOT 혹은 사물인터넷이라는 단어를 들었을 때 어떤 이미지가 떠오르고 인식이 드나요?

 

※ 또 IOT가 어떤 의미를 가지고 있을까요?

 

 

IoT는 Internet of Things를 줄인 약자로 우리나라에서는 '사물인터넷'이라고도 불립니다.

우리가 흔히 아는 '사물'과 어떤 관계가 있는 걸까요? 위의 문맥에서 가리키는 '사물'은 네트워크에 연결할 수 있는 주변의 모든 가전제품 및 물건을 다 포함하고 있습니다. 예를 들어 작게는 우리가 차는 시계, 옷 등 액세서리부터 시작해서 크게는 일상생활에서 쓰이는 가전제품, 자동차, 집까지 포함됩니다. 이러한 '사물'들이 네트워크에 연결된다면 IoT에서 말하는 사물인터넷이 되는 것입니다.

IoT는 우리가 일상생활에서 인터넷(웹) 및 메신저(모바일 앱) 등을 통하여 서로 정보를 주고받는 것처럼 네트워크에 연결된 '사물'들끼리 정보를 공유하여 유익한 정보를 생산하며, 사람의 개입 없이[조작 X, (ex) 리모컨으로 티브이를 키지 않는다] 할 수 있습니다.

 

단적인 예로는 우리가 실생활에서 자주 사용하는 애플워치 및 갤럭시 워치 등 디지털 기기들은 웨어러블 디바이스라고 불리고 있습니다. 이러한 웨어러블 디바이스 또한 IoT 기능을 가지고 있습니다. 우리가 이러한 웨어러블 디바이스를 착용하였을 때 센서를 통해 별도의 조작 없이 측정되는 걸음수, 수면시간 등은 모두 기기 내에 기록이 되어, 데이터로 변환이 되며 다른 기기에도 데이터(걸음수, 수면시간)들이 전송 및 연동되는 것 또한 사물인터넷의 원리 중 하나입니다. 물론 클라우드를 기반으로 스토리지에 저장 및 연동되어서 정보를 공유하는 원리하고도 헷갈릴 수도 있습니다.

 

알고리즘이 주어진 경우에는 알고리즘의 연산 수행 횟수를 파악해 함수로 표현할 수 있어야 합니다. 연산 수행 횟수란 선언 및 초기화 문이난 조건문, 반복문을 제외한 순수한 실행문으로, 산술연산 뿐만 아니라 출력문이나 return문이 수행되는 횟수를 포함합니다. 

 

특히 산술연산은 하나의 식 내에 포함된 연산자의 수만큼 실행된다고 가정하고 연산횟수를 파악합니다. 예를 들어

a= (a+b) / c + 1 의 경우 연산 과정이 다음과 같습니다.

 

x = a + b,                     y = x / c         ,            a = y + 1

 

그러므로  a = (a+b) / c + 1의 연산 실행 횟수는 3이 됩니다.

 

하나의 문제를 해결하기 위한 다양한 알고리즘 중 가장 효율성이 좋은 것을 선택하기 위해서는 알고리즘의 수행시간, 차지하는 기억 공간 등의 비용으로 판단합니다.

 

복잡도( Complexity:O(n) )

 

알고리즘 수행 시 필요한 시간 또는 공간 비용

 

1. 시간 복잡도 (Time Complexity)

- 프로그램이 수행되는 시간

 

2. 공간 복잡도 (Space Complexity)

- 프로그램이 차지하는 기억 공간

 

f(n) = O(g(n))     f  ,  g: 음수값을 갖지 않는 함수

 


알고리즘은 복잡도가 낮을수록 효율적입니다. 즉, 수행 시간이 짧거나 기억 공간을 적게 사용하는 알고리즘이 효율적이라고 할 수 있습니다. 그런데 최근 하드웨어 기술의 발달로 기억장치에 대한 비용이 줄어 기억 공간보다는 수행 시간에 단축에 대해 더 고려하고 있습니다. 그래서 일반적으로 복잡도는 시간 복잡도를 의미하게 됩니다.

 

알고리즘의 복잡도는 'Big-O 표기법'을 사용하는데 복잡도 f(n) = O(g(n))는 "f(n)은 g(n)의 차수"라고 읽습니다.

 

이 복잡도는 f(n)은 n ≥ n0 인 모든 자연수 n을 입력으로 하는 알고리즘이 수행될 때, 그 수행시간이  f(n) ≥ c * g(n)이 되는 양의 정수 c와 n이 존재하면 성립하는 공식으로 알고리즘이 n개의 입력으로 수행될 때, 그 수행 시간이 |g(n)|에 양의 정수 c를 곱한 것보다 같거나 작은지를 확인하면 됩니다.

 

 

 

코끼리를 냉장고에 넣는 법은 다음과 같이 표현할 수 있습니다.

 

 

1) 냉장고 문을 연다.

2) 코끼리를 냉장고에 넣는다.

3) 냉장고 문을 닫는다.

 

위와 같은 설명도 어떻게 보면 하나의 알고리즘입니다. 이와 같이 알고리즘을 일반적인 언어로 작성할 수 있지만 순서도와 의사코드와 같은 표현으로 작성할 수도 있습니다.

 


 

순서도(Flow Chart)

- 명령의 종류와 기능에 따라 도표를 만들고 명령들의 순서대로 도표를 나열해 표현하는

 

 

의사코드(Pseudo-code)

- 일반적인 언어와 프로그램 코드를 적절히 이용해 명령어들을 나열한 방식입니다.

 

 

 

 

 

알고리즘(Algorithm)이란 문제를 해결하기 위한 체계적인 단계를 뜻합니다.

 

알고리즘은 입력부터 출력에 이르기까지 모든 단계를 포함하는 것으로 하나의 문제를 해결하더라도 다양한 알고리즘이 존재할 수 있습니다. (예를 들어 똑같은 수학 문제를 푸는데 있어서도 여러가지 방식의 공식을 사용해서 문제를 푸는 것과 같다고 볼 수도 있습니다.)

 

*** 무엇보다도 알고리즘은 가장 효과적인 것을 선택하는 것이 중요합니다. ***

 

 

 


 

 

 

알고리즘은 다음과 같은 특성들을 가지고 있습니다.

 

1. 입력 (Input)

문제와 관련된 입력이 반드시 존재해야 합니다.

 

2. 출력 (Output)

입력을 처리한 출력(결과)이 반드시 존재해야 합니다.

 

3. 정확성 (Correctness)

입력을 이용한 문제 해결 과정과 출력은 논리적이고 정확해야 합니다.

 

4. 유한성 (Finitenss)

입력에 제한된 개수의 명령 단계를 거쳐 출력을 내고 반드시 종료되어야 합니다.

 

5. 효율성 (Effectiveness)

문제 해결 과정이 효율적이어야 합니다.

 

6. 일반성 (Generality)

같은 유형의 문제에 대해 항상 적용될 수 있어야 합니다.

 

7. 확정성 (Definiteness)

같은 입력에 대해 출력이 항상 확정적이어야 합니다.

 

 

 

 

 

저번 포스트에서는 어셈블러에 대하여 알아보았습니다. 이번 포스트에서는 프리 프로세서를설명하고 후에 세세한 설명과 예를 통해 풀어나갈 예정입니다.

 

전처리기라고도 불리는 프리 프로세서는 소스 프로그램과 목적 프로그램이 모두 고급 언어인 번역기로, 프로그래밍 언어에 유용한 기능을 추가하여 언어를 확장하는 역할을 합니다.프리 프로세서는 일반적으로 코볼 언어로 작성된 프로그램을 가지고 있지만 코볼 컴파일러가 없는 경우에는 실행할 수 없습니다. 하지만 코볼 컴파일러는 없어도 C 컴파일러가 있다면 실행해볼 수 있습니다.

코볼 언어로 작성된 프로그램을 C 언어로 작성된 프로그램으로 변환하고, C 언어로 변환된 프로그램을C 컴파일러에서 컴파일 및 실행하면 됩니다. 이때 코볼 언어로 작성된 프로그램을 C 언어로 작성된프로그램으로 변환하는 프로그램을 코볼-TO-C 프리프로세서라고 합니다.

 

 

즉 코볼-TO-C 프리프로세서나 C 컴파일러​가 있다면 코볼 컴파일러가 없어도 코볼 언어로 작성된 프로그램을 컴파일하여 실행할 수 있습니다.

 


 

◎ 프리 프로세서의 헤더 파일(header file)이 포함된 파일 포함(file inclusion) 기능

- C 언어에서 사용자가 #include<stdio.h>라는 문장을 작성했다면 프리 프로세서가 컴파일하기 전에 #include<stdio.h>를 삭제하고, 그 자리를 입출력과 관련된 표준 함수 stdio.h의 내용으로 대체합니다.

 

◎ 매크로(Macro) 기능

- 프리 프로세서는 매크로로 정의된 부분에 대해 컴파일하기 전에 매크로의 내용으로 확장시킵니다.

예를 들어#definemax 45는 이 프로그램에서 max가 나타날 때마다 그것을 45로 바꿔줍니다.

 

◎ 조건부 컴파일(Conditional compile) 기능

- 조건부 컴파일은 조건에 따라 소스 프로그램의 일부분을 선택적으로 삽입하거나 삭제하는 기능을 말합니다. 예를 들면아래의 그림과 같습니다.

 

 

 


 

※ 오늘은 '프리 프로세서'에 대하여 알아보았습니다.

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

#컴퓨터공학#컴파일러#컴파일러의필요성#프리프로세서

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

[컴파일러] 어셈블러  (0) 2019.09.29
[컴파일러] 번역기의 종류  (0) 2019.09.29
[컴파일러] 컴파일러는 왜 필요할까?  (0) 2019.09.27

 

 

저번 포스트에서는 번역기의 종류에 대하여 알아보았습니다. 이번 포스트에서는 어셈블러를 설명하고 후에 세세한 설명과 예를 통해 풀어나갈 예정입니다.

어셈블러는 어셈블리어로 작성된 소스 프로그램을 그에 대응하는 기계어로 번역된 목적 프로그램으로 변환해주는 번역기이고, 어셈블리어는 기계어를 사람이 좀 더 이해하기 쉽도록 기호화한 것입니다. 어셈블리 명령어(instruction)는 목적 기계에 따라 다르게 표현되는데 [아래의 그림]에서 예제를 다루어 보았습니다.

 

 


 

※ 어셈블리 명령어의 예

 

 

LOAD R1, a 코드는 변수 a에 있는 값을 레지스터 R1에 적재하라는 것이고, ADD R1, #2 코드는 레지스터 R1에 있는 값과 상수 2를 더하여 레지스터 R1에 저장하라는 것이며, 마지막으로는 STORE b, R1 코드는 레지스터 R1에 저장되어 있는 값을 변수 b에 저장하라는 것이다. 이렇게 하면 치환문 b = a + 2를 계산하는 코드입니다.

어셈블러를 구현하는 방법은 여러 가지가 있는데, 그중에서 가장 많이 사용되면서 가장 간단한 형태는 2-패스(two pass) 어셈블러입니다. 여기서 하나의 패스란 하나의 입력 파일을 단 한 번만 읽는 것으로 구성되는 단위를 말한다. 즉 2-패스 어셈블러는 2개의 패스로 구성됩니다.

첫 번째 패스에서는 메모리를 표시하는 모든 식별자를 찾아내고 그 식별자들을 기호표(symbol table)에 저장합니다. 예를 들어 [어셈블리 명령어의 예]의 코드를 읽으면 [아래의 그림, 예제 2]와 같은 항목을 포함하는 기호표가 만들어집니다. [예제 2]에서는 하나의 단어(word)가 4바이트로 구성되고 각 식별자의 주소가 0바이트부터 시작한다고 가정했습니다.

 

예제 2, [어셈블리어 명령어에 대한 식별자의 어셈블러 기호표]

 

 

두 번째 예제에서는 각 연산 코드를 기계어에서 수행될 수 있는 비트의 표현으로 나타냅니다. 예제 2의 어셈블리 명령어에 대한 가상적인 기계어는 아래의 그림과 같습니다.

 

 

예제 3 [어셈블리어 명령어에 대한 식별자의 어셈블러 기호표]에 대한 기계어

 

 

 

 

예제 3에서 첫 번째 4비트는 명령어로 0001은 LOAD, 0011은 ADD, 0010은 STORE을 나타냅니다. LOAD는 메모리에서 레지스터로 자료를 옮기고, STORE는 레지스터에서 메모리로 자료를 옮깁니다. 그다음 2비트는 레지스터를 표시하는 것으로 여기서 01은 레지스터 1을 의미합니다.

이어서 그다음 2비트는 태그를 나타내는데, 00은 다음의 8비트가 메모리 주소를 가리키는 일반적인 주소 방식(Ordinary Address Mode= 명령의 주소부가 피연산자가 저장되어 있는 기억장치의 주소를 지시) 일 때, 10은 다음의 8비트가 피연산자인 직접 번지 지정 방식(Immediate address mode= 주소의 값 자체가 피연산자)일 때 사용됩니다. *는 각각의 피연산자가 재배치(relocatable) 가능 기계어에서 재배치 비트임을 나타내는 것입니다.

 


 

※ 오늘은 '어셈블러'에 대하여 알아보았습니다.

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

#컴퓨터공학 #컴파일러 #컴파일러의필요성 #어셈블러 #기계어

 

 

지난 포스트에서는 컴파일러의 필요성에 대하여 알아보았습니다. 이번 포스트에서는 번역기의 종류의 큰 틀을 설명하고 후에 세세한 설명과 예를 통해 풀어나갈 예정입니다.

 

번역기는 하나의 프로그래밍 언어로 작성된 프로그램을 그와 동등한 의미를 가진 다른 프로그래밍 언어로 된 프로그램으로 변환하는 프로그램입니다. 이때 입력되는 프로그램을 소스 프로그램(Source Program)이라 하고 소스 프로그램을 기술하는 언어를 소스 언어(Source Language)라고 부릅니다.

또한 출력되는 프로그램을 목적 프로그램(Object Program)이라 하고, 목적 프로그램이라 하고, 목적 프로그램을 기술하는 언어를 목적 언어(Object Language, Target Language)라 합니다.

 


 

번역기의 종류는 아래의 그림과 같이 어셈블러, 컴파일러, 프리프로세서(Preprocessor), 인터프리터(Interpretor)등이 있는데, 이 가운데 가장 대표적인 번역기는 바로 컴파일러입니다.

 

 

 

그림에서 보듯이 어셈블러는 어셈블리어로 작성된 소스 프로그램을 그에 대응하는 기계어로 번역된 목적 프로그램으로 변환해주는 번역기입니다. 그리고 컴파일러는 고급 언어인 C나 코볼로 작성된 소스 프로그램을 그에 대응하는 어셈블리어나 기계어로 번역된 목적 프로그램으로 변환해주는 번역기입니다.

이때 소스 언어가 C이면 C 컴파일러라 하고,소스 언어가 코볼이면 코볼 컴파일러라고 합니다. 마찬가지로 프리프로세서는 프로그래밍 언어에 유용한 기능을 추가하여 언어를 확장하는 역할을 하는 것으로, 소스 프로그램과 목적 프로그램이 모두 고급 언어인 번역기를 말합니다. 한편 인터프리터는 다른 번역기와 달리 문장 단위로 번역과 동시에 실행한 후 그 결과를 출력하는 번역기입니다.

 


 

※ 오늘은 '번역기의 종류'에 대하여 알아보았습니다.

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

#컴퓨터공학 #컴파일러 #컴파일러의필요성 #번역기의종류

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

[컴파일러] 프리 프로세서  (0) 2019.09.29
[컴파일러] 어셈블러  (0) 2019.09.29
[컴파일러] 컴파일러는 왜 필요할까?  (0) 2019.09.27

+ Recent posts