트리(tree)란?

트리 구조란 정보의 항목들이 가지로 연결될 수 있게 데이터가 조작되는 것이며, 가계표, 족보, 왕조의 나열 등에서 쉽게 찾아볼 수 있다.
가계표를 예를 들어 설명을 하면 최 상단에 조부모님이 계시고 그 아래로 아버지와 어머니, 동생 친척들이 쭉 나열이 되는데, 이러한 조직 체계를 트리를 통해 나타낼 수 있다.

트리 구조에서 노드 란 각 항목들을 의미하며 한 정보 아이템에서 다른 노드로 뻗어진 가지를 포함한 개념이다.
각 노드는 아래로 계속해서 가지를 뻗어나갈 수 있는데, 한 노드에서 뻗어져 나간 가지들(서브트리) 의 수를 그 노드의 차수 라고 부른다.
또한, 차수가 0인 노드를 리프 혹은 단말 노드 라고 부르며, 뻗어나간 구조의 상위의 노드를 아래 노드의 부모(parent) 라 하고 아래 노드를 상위 노드의 자식(child) 이라고 부른다. 또한 한 노드에서 뻗어져 나온 병렬관계의 노드를 서로의 형제(sibling) 이라고 부른다.

특정 노드의 차수와 구분하여 트리의 차수 트리에 있는 노드의 최대 차수를 말한다.

이진 트리

다시 가계표의 예를 들면 한 부모 밑에는 수많은 자식들이 생길 수 있으나, 컴퓨터가 이를 처리하는 시점에서 특정 부모노드 아래에 숫자를 알 수 없는 자식들이 존재하게 된다면 포인터 필드가 가변적이기에 효율적으로 메모리를 사용할 수 없다. 이 때문에 일정한 크기의 노드를 사용하기 위한 트리의 표현법이 나타나게 되었고, 한 노드가 가지만을 가지도록 만들어진 트리를 이진 트리 라고 한다.

제일 위의 노드(root)로 부터 2배씩 증가하며 가지들이 뻗어나와 크리스마스 트리 형태를 띄는 형태를 이진트리라고 부르며 모든 노드들이 규칙적으로 2개씩 가지를 쳐 나가 각 층의 노드가 꽉꽉 들어차면 이를 포화 이진 트리 라고 한다.
깊이가 k인 포화 이진트리의 노드 수는 (2^k-1)개 이다.

컴퓨터에서는 이러한 이진트리를 메모리에 저장할 방법을 찾게 되었고 최 상단 노드부터 차례로 메모리에 저장을 하게 되면 포화 이진트리가 아닌 대부분의 이진트리에서는 메모리 중간 중간이 비게 되어 효율적인 메모리 사용에 어려움을 겪게 되었는데, 이를 해결하기 위해 열결표현 방식을 사용하여 각 노드가 다른 노드의 링크를 연결하여 포인터를 들고 있는 방식으로 저장하게 되었다.

어떠한 트리도 이진 트리로 표현할 수 있다.

다음은 C 언어를 이용한 이진 트리의 구현이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdlib.h>
#include <stdio.h>
/*node 구조체로 *treePointer 라는 별칭 선언*/
typedef struct node *treePointer;
/*node 구조체를 선언한다.*/
typedef struct node{
char data;
treePointer leftChild, rightChild;
} node;

treePointer createNode(char newData)
{
treePointer newNode = (treePointer)malloc(sizeof(node));
newNode->leftChild = NULL;
newNode->rightChild = NULL;
newNode->data = newData;

return newNode;
}

void inorder(treePointer ptr)
{
if(ptr){
inorder(ptr->leftChild);
printf("%c", (*ptr).data);
inorder(ptr->rightChild);
}
}

/*추가된 노드를 출력하는 부분*/
int main()
{
treePointer nodeA = createNode('A');
treePointer nodeB = createNode('B');
treePointer nodeC = createNode('C');
treePointer nodeD = createNode('D');
treePointer nodeE = createNode('E');
treePointer nodeF = createNode('F');
treePointer nodeG = createNode('G');
treePointer nodeH = createNode('H');

(*nodeA).leftChild=nodeB;
(*nodeA).rightChild=nodeC;
(*nodeB).leftChild=nodeD;
(*nodeB).rightChild=nodeE;
(*nodeD).rightChild=nodeG;
(*nodeC).leftChild=nodeF;
(*nodeF).rightChild=nodeH;
inorder(nodeA);
}

이진 트리 순회

앞서 설명한 이진 트리를 조회하기 위해서 다양한 방법을 사용하는데, 한 노드에서 왼쪽으로 이동(L), 오른쪽으로 이동(R), 노드 방문(V) 의 순서에 따라 중위 순회, 후위 순회, 전위 순회로 구분한다.

먼저 전위 순회(preorder traversal) 는 이름 그대로 노드를 먼저 방문하는 경우 즉, VLR의 순서로 노드를 방문하는 경우이다.
후위 순회(postorder traversal) 은 노드를 제일 마직막에 방문하는 경우 즉, LRV의 순서로 노드를 방문하는 경우이다.
중위 순회 란 노드를 중간에 방문하는 경우 즉, LVR의 순서로 노드를 방문하는 경우이다.

중위 순회를 하는 경우를 C 코드로 나타내면 다음과 같다.

1
2
3
4
5
6
7
8
void inorder(treePointer ptr)
{
if(ptr){
inorder(ptr->leftChild);
printf("%c", (*ptr).data);
inorder(ptr->rightChild);
}
}

위의 코드를 살펴보면 반복법이 아닌 순환법을 이용하여 즉, 스택의 도움 없이 순회를 진행하는데 이는 스택을 이용하여 스택에 노드를 저장하고 제거하는 방식으로도 순회가 가능하다. 이러한 순회를 반복적 중위 순회 라고 하며 이를 C 코드로 구현하면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void iterInorder(treePointer ptr){
int top = -1; /*스택 초기화*/
treePointer stack[MAX_STACK_SIZE];
for(;;){
for(;node;node=node->leftChild)
push(node);/*스택에 삽입*/

node=pop();/*스택에서 제거*/
if(!node)/*스택이 비어있는 경우 중지*/
break;
printf("%d", node->data);
node=node->rightChild;
}
}

예제

이진 트리에서 리프 노드의 수를 세는 C 함수를 작성하여라.

1
2
3
4
5
6
7
8
9
10
11
12
int totalCount=0;
void countLeaf(treePointer ptr){
if(ptr&&(!(*ptr).leftChild)&&(!(*ptr).rightChild)){
totalCount++;
printf("\n리프 노드: %c, count:%d\n", (*ptr).data, totalCount);
}
if(ptr){
countLeaf((*ptr).leftChild);
printf("%c",(*ptr).data);
countLeaf((*ptr).rightChild);
}
}

스레드 이진 트리

2n개의 링크 중 n+1개가 null link 이므로 효율성이 떨어지는 문제가 생기게 되고 이를 해결하기 위해 null link에 포인터를 넣어 다른 노드의 링크를 거는 것을 스레드 라고 한다.

이원 탐색 트리(BST, Binary Search Tree)

이원 탐색 트리는 탐색, 삽입, 삭제 연산에 있어서 지금까지 공부했던 어떤 자료 구조보다도 성능이 좋다.
이원 탐색트리의 모든 원소는 키를 가지고 어떤 두 원소도 동일한 키를 갖지 않으며, 왼쪽 서브트리가 존재한다면 그 키들은 루트의 키보다 작고 오른쪽 서브트리가 존재한다면 루트의 키보다 크다. 또한, 왼쪽과 오른쪽 서브트리도 모두 이원탐색 트리이다.

이원 탐색트리의 탐색

탐색은 루트부터 시작하여 루트와 키 값이 같다면 탐색은 종료된다. 탐색하고자 하는 키 값이 루트의 키보다 작다면 왼쪽 서브트리를 탐색하고 크다면 오른쪽 서브트리를 탐색한다. 왼쪽과 오른쪽 서브트리는 모두 이원탐색 트리이므로 각각을 다시 탐색하는 순환 탐색 방식을 사용한다.

다음은 이원 탐색 트리의 순환적 탐색을 구현한 프로그램이다.

1
2
3
4
5
6
7
element * search(treePointer tree, int key){
if(!root) return NULL;
if(k == root->data.key) return &(root->data);
if(k<root->data.key)
return search(root->leftChild, k);
return search(root->rightChild, k);
}

아래는 동일한 기능의 반복 함수로 구현한 프로그램이다.

1
2
3
4
5
6
7
8
9
10
11
element* iterSearch(treePointer tree, int k)
{
white(tree){
if(k==tree->data.key) return &(tree->data);
if(k<tree->data.key)
tree = tree->leftChild;
else
tree = tree->rightChild;
}
return NULL;
}

Time Complexity: O(h)

BST 에서의 찾는 시간은 찾고자 하는 노드의 높이만큼 분기를 수행하므로 O(h) 이다.

INSERTION IN BST

이원 탐색 트리에서의 삽입 개념도

Time Complexity: O(h)

BST 에서의 삭제는 search 후에 단순 삽입으로 search 시의 time complexity와 같은 complexity 를 가진다.

DELETION IN BST

이진 탐색 트리에서의 삭제 개념도

Time Complexity: O(h)

BST 에서의 삭제는 다음과 같이 진행된다.

  1. BST에서 해당 노드를 찾음
  2. 해당 노드를 삭제하고, maximum value in left subchild 로 대체 하거나 혹은 minimum in right subchild 로 대체한다.
  3. 대체된 노드에 대한 삭제를 진행한다. 이 경우 해당 노드는 차수가 0이거나 혹은 1 이므로 삭제는 매우 간편하다.

위의 각 과정별로 시간 소모를 생각해 보면, 노드를 찾는데에 O(h), 삭제하고 서브 트리에서 값을 찾는데에 O(h) 삭제에 1 이므로 BST 에서 deletion 시에 time Complexity 는 O(h) 이다.

선택 트리

승자 트리

다음은 8개의 런(k=8) 을 가진 승자 트리의 개념도 입니다.

선택 트리의 개념도

패자 트리

다음은 위의 승자 트리에 대응하는 패자 트리의 개념도 입니다.

패자 트리의 개념도

분리 집합의 표현

이진 트리의 개수 계산

AVL 트리

AVL 트리란 균형 이진 트리의 한 종류이며, 이원 탐색트리가 항상 완전 이진트리로 유지되도록 한 트리입니다.

탐색, 삽입, 삭제 시간: O(logn)

AVL 트리에서 각 노드는 균형 인자(balance factor) 를 가지는데, 이는 왼쪽 트리의 높이에서 오른쪽 트리의 높이를 뺀 값으로 높이의 균형도를 나타냅니다.

balance factor = h_L - h_R

AVL 트리에서는 어떤 서브트리 T 에서도 BF(T) 의 절대값은 1 이하입니다.

AVL 트리에서의 삽입

LL rotation

LL 로테이션

RR rotation
LR rotation

LR 로테이션


1. 한쪽 끝과 양쪽 끝 우선순위 큐

우선순위 큐(priority queue) 는 각 원소가 연관된 우선순위를 갖고 있는 원소들의 모임이다.
가령 시스템의 작업 우선도를 설정해 줄 때에는 작업들을 우선 순위에 따라 분류해야 하며, 2개의 서버로 이루어진 시스템의 경우에 하나의 시스템이 사고로 인해 종료되는 경우 반대쪽 서버로 그 작업 내역들이 병합되어야 하는데 이러한 경우 우선순위 큐를 통해 두 작업 리스트를 병합해야 한다.

이러한 우선순위 큐 한쪽 끝 우선순위 큐양쪽 끝 우선순위 큐 가 있으며, 한쪽 끝 우선순위 큐는 최대 우선순위 큐최소 우선순위 큐 로 나뉜다.

최소 우선순위 큐 에 의해 지원되는 연산은 다음과 같다.
SP1. 최소 우선순위를 가진 원소의 반환
SP2. 임의 우선순위를 가진 원소의 삽입
SP3. 최소 우선순위를 가진 원소의 삭제

이러한 우선순위 큐를 잘 표현하기 위한 고전적인 자료 구조로써 히프(heap) 를 사용한다.

양쪽 끝 우선순위 큐는 최소 우선순위 큐와 최대 우선순위 큐가 하나로 합해진 최소-최대 우선순위 큐이다.

실제 활용도 측면에서, 양쪽 끝 우선순위 큐는 네트워크 버퍼를 구현하는 데 사용되는데 네트워크 링크를 통해 전송되기를 원하는 패킷들을 가지고 있는 경우 가장 높은 우선순위를 가진 패킷이 전송되고 삭제 되는 최대 삭제 가 행해지는 반면, 네트워크 내의 다른 곳으로 부터 새로운 패킷이 도착하였는데 버퍼가 가득 차 있다면 우선 순위가 가장 낮은 패킷을 지우는 최소 삭제 가 일어나게 된다. 이처럼 작업 큐의 양쪽에서 삽입과 삭제가 가능한 큐를 양쪽 끝 우선순위 큐라고 부른다.

좌향 트리

좌향트리는 합병성 우선순위 큐의 효율적 구현을 제공한다.
좌향 트리의 종류에는 HBLT(Height Biased Leftist Tree)와 WBLT(Weight Biased Leftist Tree)가 있는데, 일반적으로 HBLT를 좌향트리하고 부른다.

이항히프(B-Heap)

좌향 트리에서 지원되는 것과 같은 기능을 수행한다. 개별적인 연산을 수행하는 데 걸리는 시간보다 우선순위 큐의 순차를 수행하는데 걸리는 시점에 관심이 있다.
이항 히프란 최소 트리의 집합이며, 최소 트리 가운데 최소값을 갖는 트리를 가리키는 하나의 포인터가 가르키게 된다.

명령어 집합 구조가 구현의 여러 가지 측면을 어떻게 결정 하는지, 또 여러가지 구현 전략이 클럭 속도와 CPI에 어떻게 영향을 미치는지 살펴볼 기회를 갖게 될 것이다.
명령어 종류에 관계없이 어떤 명령어 던지 처음 두 단계는 다음과 같이 동일하다.

  1. 프로그램 카운터(PC)를 프로그램이 저장된 메모리로 보내어 메모리로부터 명령어를 가져온다.
  2. 읽은 레지스터를 선택하는 명령어 필드를 사용하여 하나 또는 두 개의 레지스터를 읽는다.

파이프라이닝에 대한 개관

파이프라이닝이란 여러 명령어가 중첩되어 실행되는 구현기술로써 기존의 단일 사이클 구조에서는 ALU 등 여러 장치가 다른 명령어를 실행하는 동안에는 동작하지 않는 것이 효율이 매우 떨어지기에 각 명령어를 처리할 수 있는 자원이 존재한다면 이를 병렬로 실행시켜 처리량을 올리는 기술이다.

개요: 시스템 생명 주기

포인터와 동적 메모리 할당

알고리즘 명세

데이터 추상화

성능 분석

본 강의의 목적 중 하나는 프로그램에 대한 평가 능력을 향상시키는 것이다.
프로그램의 판단함에 있어서 다양한 기준이 있지만, 크게는 컴퓨터와 상관 없이 시공간의 추산에 초점을 두는 성능 분석(performance analysis) 과 컴퓨터에 의존적인 실행 시간을 얻어내는 성능 측정(performance measurement) 이 있다.

이번 강의 에서는 성능 측정은 배제하고 성능 분석에 초점을 두어 강의를 진행하며 성능 분석은 다음의 두 복잡도로 분석을 진행한다.

  1. 공간 복잡도
  2. 시간 복잡도

공간 복잡도

공간 복잡도의 정의는 프로그램을 실행시켜 완료하는 데 필요로 하는 공간의 양으로, 실제 메모리를 차지하는 양을 나타낸다. 각 각의 변수가 얼마나 많은 메모리를 차지하는 지 등을 다루며 이러한 공간 복잡도는 고정 공간 요구가변 공간 요구 로 나뉘게 된다.

고정 공간 요구
프로그램 입출력의 횟수나 크기에 관계없는 공간 요구를 의미한다.
가령 명렁어 공간, 단순 변수, 상수 고정 크기의 구조화 변수 등을 포함한다.

가변 공간 요구
해결하고자 하는 문제의 특정 인스턴스 I에 의존하는 크기를 가진 구조화 변수들을 위해 필요로 하는 공간이다.

시간 복잡도

컴파일 시간과 실행 시간을 합한 것이다.

서론

컴퓨터 하드웨어에게 일을 시키려면 하드웨어가 알아들을 수 있는 언어로 말을 해야하며, 컴퓨터 언어에서의 단어를 명령어 라고 하며 그 집합을 명령어 집합 이라고 한다.
본 강의에서는 명령어 집합의 하드웨어 표현방식 및 상위 수준 언어와의 관계를 보이며, 이를 통해 내장 프로그램의 개념을 이해한다.

하드웨어 연산

기본적으로 컴퓨터는 산술연산을 할 수 있으며 다음과 같은 명령어를 사용한다.

1
add a, b, c

위의 명령어는 b+c를 한 결과값을 a에 담는 식이다.

3. 피연산자

레지스터 라고 하는 하드웨어로 직접 구현된 특수 위치 몇 곳에 있는 것만 사용할 수 있다.
MIPS 구조에서 이러한 레지스터의 크기는 32비트(4 byte) 이며 총 32개로 레지스터의 갯수가 제한 되어 있으며 본 강의에서는 각 레지스터 마다의 성질을 보여주기 위해 $뒤의 숫자 가령 $t0와 같은 방식으로 레지스터를 표기한다.
레지스터의 수가 제한된 이유는 레지스터가 아주 많아지면 전기 신호가 더 멀리까지 전달되어야 하므로 클럭 사이클이 길어지기 때문이다.

레지스터 안에는 변수, 명령어 등이 저장될 수 있는데,프로그래밍 언어에는 단순한 변수 이외에도 레지스터 개수보다 훨씬 많은 데이터 원소수가 있을 수 있다.
산술연산은 레지스터에 의해서만 실행되므로 메모리의 값을 레지스터에 옮겨오기 위해서는 이들 사이에 데이터를 주고받기 위한 명령어가 필요한데, 이를 데이터 전송 명령어 라고 한다. 메모리에서 레지스터로 데이터를 옮기는 실제 명령어는 다음과 같다.

1
lw t0, 8($s3)

한 주소블록은 32비트(즉, 4byte)를 기준으로 하기 때문에
위 명령은 t0에 $s3에서부터 8번째 데이터를 담는 것이다.
즉 실제 주소는: $s3 + 8*4byte에 위치한다.

레지스터 연산을 할때 상수를 더하는 경우가 있는데, 이 경우에는 상수만을 위한 명령어 addi 등을 사용한다.
이 경우 상수값을 메모리에서 가져오는 것이 아니라 프로세서 내에서 바로 더해 줌으로써 훨씬 빠르게 처리를 할 수 있다.

상수 덧셈의 예

1
addi $s3, $s3, 4

어셈블리어의 기계어 표현

레즈스터 내의 기계어 명령어 필드

R타입

op rs rt rd shamt funct
연산자 피연산자 피연산자2 목적지 자리이동 양 기능
6bit 5bit 5bit 5bit 5bit 6bit

I 타입
| op | rs | rt | constant+address |
|:—- |:—- | —- | —————- |
| 6bit | 5bit | 5bit |21bit|

하드웨어의 프로시저 지원

프로시저는 일종의 함수 역할을 하는 것으로 전달인수 레지스터4개와 반환 레지스터 2개, 복귀주소 1개로 이루어져 있다.

서비스 소개서를 작성함에 있어 가장 핵심이 되는 것은 바로 청자가 원하는 것이 무엇인지를 명확하게 파악하고 그리고 우리 제품을 가능한한 알기 쉽고 직관적으로 이해 할 수 있도록 하는 것이다.

서비스 소개서의 시작은 고객의 관심을 사로잡을 수 있도록 상대방의 니즈 혹은 현재 하고있는 비즈니스에 명확하게 도움이 되는 포인트를 설득력있고 알기쉽게 제시한다. 이렇게 독자의 마음을 열었다면, 그 다음으로는 우리의 제품이 해당 니즈에 어떻게 도움이 되며, 아주 쉽게 우리 제품에 대해 명확한 이해가 수반되어야 한다. 이때의 기준은 독자가 우리의 서비스 소개서를 읽은 뒤에 다른 누군가에게 가서 우리의 제품에 대해 명확하게 설명할 수 있을 정도가 바람직하다.

서론

1940년 전자식 컴퓨터가 등장한 이래로 컴퓨터는 정보 혁명을 주도하며 컴퓨터와 관련 사업을 빠르게 발전시켰다.
스마트 가전제품 부터 슈퍼 컴퓨터 까지 삶의 다양한 분야에서 컴퓨터가 활용되고 있으며 크게 다음과 같은 세가지 응용분야에서 사용된다.

  • 개인용 컴퓨터
  • 서버
  • 임베디드 컴퓨터

개인용 컴퓨터는 많은 사람들이 잘 알고있듯이 가정 내에 보급된 pc를 말하며, 가정 및 비즈니스에서 산업용으로도 사용되고 있다.
서버는 과거 대형 컴퓨터로 불리던 것의 현대적 형태로써 보통 네트워크를 통해 접근되며 소규모 비즈니스 서버 등 주로 산업에서 인터넷을 통한 서비스 공급의 목적으로 사용되고 있다.
가장 많이 사용되는 임베디드 컴퓨터는 한 가지 응용을 수행하거나 서로 연관된 일련의 프로그램을 실행하도록 설계된 컴퓨터로 많은 가전기기 및 제품들에 탑재되어 있다.

단순 컴퓨터의 출생이 가지는 의미를 넘어 컴퓨터의 영향으로 세계 IT 산업은 송두리째 뒤흔들리고 있는 분야가 있는데, 그것은 바로 개인 휴대용 기기(PMD)클라우드 컴퓨팅 을 기반으로 한 sass 이다.

개인 휴대용 기기를 통해 사람들은 어디에서나 인터넷에 연결되어 진정한 초연결 사회로 거듭나게 되었으며, 엄청난 컴퓨팅 파워가 기반이 되어야 사용 가능했던 많은 컴퓨터 기반의 서비스들이 창고 규모의 컴퓨팅(WSC: Warehouse Scale Computing)으로 알려진 클라우드 컴퓨팅을 통해 서비스 로서의 소프트웨어(sass)로 제공되고 있다.

본 강의는 David A. Patterson과 John L. Hennessy의 책을 토대로 공부한 내용을 정리하며, 다음과 같은 내용을 배운다.

  1. 상위 수준으로 작성된 프로그램이 어떻게 하드웨어로 번역되고 동작하는가?
  2. 소프트웨어와 하드웨어 사이의 인터페이스는 무엇이며, 소프트웨어는 어떻게 필요한 일을 하드웨어에게 지시하는가?
  3. 프로그램의 성능을 결정하는 요소는 무엇이며, 프로그래머는 어떻게 성능을 개선하는가?
  4. 성능 개선을 위해 하드웨어 설계자는 어떤 기술을 사용하는가?
  5. 에너지 효율성을 개선하기 위해 하드웨어 설계자는 어떤 기술을 사용할 수 있는가?
  6. 최근 순차처리에서 병렬처리로 넘어가는 이유는 무엇이며 결과는 어떠한가?
  7. 컴퓨터 구조 분야의 어떤 위대한 아이디어들이 컴퓨팅의 기초를 닦았는가?

컴퓨터를 조작하는 명령어는 어떻게 작동하는가?

컴퓨터 하드웨어는 아주 단순한 명령을 실행 할 수 있도록 설계되어 있으며, 많은 현대 프로그래머들이 작성하는 복잡한 코드는 적절한 변환을 통해 컴퓨터가 알기 쉬운 언어로 번역되어 하드웨어를 동작한다. 프로그래머는 코드를 작성하면서 하드웨어의 구체적인 동작은 배제하고 프로그램을 작성이 가능한데, 이는 인간의 상위 언어인 프로그램 언어를 하드웨어와 무관하게 자유롭게 작성할 수 있도록 하는 추상화 의 일환이다.
즉, 프로그래머는 추상화된 언어인 상위 언어들을 사용함으로써 컴퓨터 내의 복잡한 일들을 신경쓰지 않고 더욱 정교한 시스템을 만들어 갈 수 있다.

소프트웨어와 하드웨어의 상호작용은 다음과 같이 일어난다.

_1. 상위 수준 언어로 코드를 작성

  1. 컴파일러가 상위수준 언어를 하위 언어인 어셈블리어로 변환시켜 줌
  2. 어셈블러가 어셈블리어를 컴퓨터가 알아들을 수 있는 이진수 체계로 변환시켜 줌_

컴퓨터 구조 분야의 8가지 위대한 아이디어

  1. 무어의 법칙을 고려한 설계
  2. 설계를 단순화하는 추상화
  3. 자주 생기는 일을 빠르게
  4. 병렬 처리
  5. 파이프라이닝을 통한 성능 개선
  6. 예측을 통한 성능 개선
  7. 메모리 계층구조
    최상위 계층에는 비트당 가격이 제일 바싸지만 작고 빠른 메모리를 사용하고, 최하위 계층에는 느리지만 크고 비트당 가격이 제일 싼 메모리를 사용한다.
  8. 여유분을 이용한 신용도 개선

컴퓨터의 구성과 기본 기능

컴퓨터는 기본적으로 다음과 같은 5가지 항목으로 구성된다.

  1. 입력 유닛
  2. 출력 유닛
  3. 메모리 유닛
  4. 데이터패스 유닛
  5. 제어 유닛

출력

컴퓨터의 출력은 주로 그래픽 디스플레이를 통해 이루어 진다.
오늘날의 LCD 디스플레이는 수만개의 화상으로 이루어져 있으며, 각 화상마다 작은 트랜지스터가 배치되어 있어 전류를 정밀하게 제어하는 능동 행렬을 사용한다.
각 화상은 화소의 행렬로 구성되며, 이것을 비트맵이라 부르는 비트들의 행렬로 포현한다.
컬러 디스플레이는 각각마다 8비트씩, 모두 24비트를 사용하여 수백만 가지의 색을 표시할 수 있다.

그래픽을 지원하는 하드웨어의 중심이 되는 것은 비트맵을 기억하는 프레임 버퍼 라고 하는 부분이며, 스크린에 표시될 화상을 프레임 버퍼에 자장하였다가, 기억된 각 화소들의 비트 패턴을 재생 속도에 맞추어 그래픽 디스플레이로 보낸다.

프로세서

디바이스 안에는 집적회로라 불리는 장치들이 있는데, 이는 프로그램의 지시대로 일을 하며, 데이터패스와 제어 유닛으로 나뉜다.
또한 프로세서 내에서 처리할 데이터를 잠깐 보관하기 위해 이를 캐시 메모리 라고 한다.

성능

컴퓨터의 성능이란 두 컴퓨터에서 같은 프로그램을 실행시키는 경우에 먼저 끝나는 쪽이 더 빠른 컴퓨터라고 할 수 있을 것이다.
하지만 사용하는 사람과 컴퓨터의 목적에 따라 다른 성능 척도가 필요 하다.
가령, 개인의 입장에서는 작업 개에서 종료까지의 시간인 응답시간 이 성능의 중요한 척도일 것이고, 데이터 센터 관리자에게는 일정 시간동안 처리하는 작업의 양인 처리량 혹은 대역폭 이 더 중요한 성능의 척도일 것이다.

다양한 성능 인자들

_프로그램의 CPU 실행 시간

프로그램의 CPU 클럭 사이클 수 * 단위 클럭 사이클 시간 = 프로그램의 CPU 클럭 사이클 수 / 클럭 속도

명령어당 클럭 사이클 수(CPI)
명령어 수 * 명령어당 평균 클럭 사이클 수

CPU 시간
명령어 개수 CPI 클럭 사이클 시간

IPC(Instructions Per clock Cycle)
클럭 사이클 당 명령어 수

MIPS(Million Instructions Per Second)
명령어 개수 / (실행시간*10^6)

예제

다음은 명령어당 클럭 사이클 수를 통한 성능 비교를 보여주는 표이다.

시스템 이름 명령어 수 CPI 소요 시간
A 5 2 250ps
B 6 1.2 500ps

Express란?

Express는 자체적인 최소한의 기능을 갖춘 라우팅 및 미들웨어 웹 프레임워크이며, Express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출이다.

Installation

npm install express --save

trigger의 생성과 삭제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
DROP TRIGGER IF EXISTS `sport`.`tr_update_gameresult`;

CREATE TRIGGER `sport`.`tr_update_gameresult` BEFORE UPDATE ON sport.tb_game
FOR EACH ROW
BEGIN
-- 게임이 종료 되었는지 판단
IF NEW.COMP_CODE = '3' THEN
SET @exception = (select EXPECATE from tb_reg_game where GAME_NO = NEW.GAME_NO);

IF @exception = NEW.VIC_CODE THEN
update tb_reg_game set `HIT_RESULT` = '1' where GAME_NO = NEW.GAME_NO;
ELSE
update tb_reg_game set `HIT_RESULT` = '2' where GAME_NO = NEW.GAME_NO;
END IF;

END IF;
END;

새로 들어온 데이터 선택자 new와 기존에 있던 데이터 선택자 OLD

새로 들어온 데이터를 new로 지칭하여 attribute를 뽑아서 사용할 수 있다.

1
update tb_group set MEMBER_NUM=@memberNum where GROUP_ID = new.GM_GROUP_ID;

특정 데이터 생성 혹은 삭제시에 상위 테이블의 전체 개수 인덱스 변경하기

1
2
3
4
5
6
7
8
9
10
11
create trigger trx_updates_atrig
after insert on trx_updates for each row begin

<!-- 트리거 동작에 필요한 변수 선언 -->
DECLARE memverNum INT;
<!-- 변수에 값 넣는 sql -->
set @memberNum = ( select count(*) from tb_group_member where GM_GROUP_ID=new.GM_GROUP_ID );

<!-- 인덱스 변경 SQL -->
update tb_group set MEMBER_NUM=@memberNum where GROUP_ID = new.GM_GROUP_ID;
end//

개요

몽고디비를 서버 이전시에 필요한 코드이다.

데이터 export 하기

필요한 데이터베이스의 collection을 json 형태로 내보내는 코드이다.
이 경우 -u를 반드시 부쳐 로그인 후에 dump를 수행하도록 하여 authentication을 해 준다.
example

1
sudo mongoexport -h -h 127.0.0.1:27017 -d databaseName -c collectionName -u userName -o fileName.json

export한 데이터 import 하기

1
sudo mongoimport -h 127.0.0.1:27017 -d databaseName -c collectionName --file fileName.json
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×