Skip to content
Snippets Groups Projects
Commit 08dfa95e authored by KangHyun Kim's avatar KangHyun Kim
Browse files

add images

parent 9be55e33
No related branches found
No related tags found
No related merge requests found
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
### 컴퓨터의 구성 요소(하드웨어) ### 컴퓨터의 구성 요소(하드웨어)
<img src="./img/computer_archi.PNG" width="550px" height="300px">
Storage에 파일(a.out)이 들어있고, CPU는 input과 output 모두 메모리를 거쳐야한다. 파일을 실행하기 위해서는 storage의 파일을 메모리에 적재해야 한다. Input과 output 사이에서 메모리와 연결하는 내용을 버퍼라고 한다. Storage에 파일(a.out)이 들어있고, CPU는 input과 output 모두 메모리를 거쳐야한다. 파일을 실행하기 위해서는 storage의 파일을 메모리에 적재해야 한다. Input과 output 사이에서 메모리와 연결하는 내용을 버퍼라고 한다.
컴퓨터는 사용자, 소프트웨어(시스템 소프트웨어, 어플리케이션), 하드웨어 등으로 구성되어 있다. 컴퓨터는 사용자, 소프트웨어(시스템 소프트웨어, 어플리케이션), 하드웨어 등으로 구성되어 있다.
...@@ -61,6 +63,8 @@ tty를 통해 어떠한 터미널을 나에게 부여했는지 알 수 있다. ...@@ -61,6 +63,8 @@ tty를 통해 어떠한 터미널을 나에게 부여했는지 알 수 있다.
로컬 레포지토리의 내용들을 외부 레포지토리로 보내는 명령어이다. 로컬 레포지토리의 내용들을 외부 레포지토리로 보내는 명령어이다.
### 파이프 라인 ### 파이프 라인
<img src="./img/pipe.PNG" width="550px" height="300px">
``` main | output.txt ``` ``` main | output.txt ```
파이프 라인은 두 파일 혹은 두 리눅스 명령어의 버퍼를 서로 이어주는 방식이다. 버퍼는 메모리 안에 존재하므로 결과저긍로 파이프는 메모리 안에서 동작한다. 현재 예시로 있는 위의 명령어는 main의 stdout을 output.txt의 stdin으로 전달한다. 따라서 위의 명령어를 수행하면 main으로 출력되는 stdout이 output.txt에 저장된다. 파이프 라인은 두 파일 혹은 두 리눅스 명령어의 버퍼를 서로 이어주는 방식이다. 버퍼는 메모리 안에 존재하므로 결과저긍로 파이프는 메모리 안에서 동작한다. 현재 예시로 있는 위의 명령어는 main의 stdout을 output.txt의 stdin으로 전달한다. 따라서 위의 명령어를 수행하면 main으로 출력되는 stdout이 output.txt에 저장된다.
...@@ -107,7 +111,7 @@ cat << EOF ...@@ -107,7 +111,7 @@ cat << EOF
``` ```
a.out <<< 99 a.out <<< 99
``` ```
위의 식은 Here string이며 파일의 standard input으로 <<<의 오른쪽 string을 입력해준다. 따라서 위의 명령어는 a.out 파일의 standard input으로 99를 넣어주는 것과 같다. <<<의 경우 배쉬에서만 실행이 가능하다. 또한 <<<은 globing이 발생하지 않는다. globing은 와일드카드와 관계가 있다. 위의 식은 Here string이며 파일의 standard input으로 <<<의 오른쪽 string을 입력해준다. 따라서 위의 명령어는 a.out 파일의 standard input으로 99를 넣어주는 것과 같다. **<<<의 경우 배쉬에서만 실행이 가능하다.** 또한 <<<은 globing이 발생하지 않는다. globing은 와일드카드와 관계가 있다.
### Basic data type ### Basic data type
...@@ -159,6 +163,10 @@ const는 상수와 같으며, 한 번 초기화를 하면 더 이상 값을 바 ...@@ -159,6 +163,10 @@ const는 상수와 같으며, 한 번 초기화를 하면 더 이상 값을 바
``` ```
int *a; int *a;
void *b; void *b;
int *c; // c++ increment by 4
long long *d // d++ increment by 8
void *e // e++ increment by 1
``` ```
위와 같이 정의되어 있는 a 변수에 a++를 한다면 integer의 크기만큼 주소가 증가한다. integer의 크기는 기기와 아키텍쳐마다 다르므로 결과가 기기마다 상이할 수 있다. 위와 같이 정의되어 있는 a 변수에 a++를 한다면 integer의 크기만큼 주소가 증가한다. integer의 크기는 기기와 아키텍쳐마다 다르므로 결과가 기기마다 상이할 수 있다.
...@@ -215,7 +223,21 @@ void (*fp[4]) ...@@ -215,7 +223,21 @@ void (*fp[4])
또한 위에서 2번째 식을 통해 함수 포인터를 배열로써 정의하여 사용할 수 있다. 또한 위에서 2번째 식을 통해 함수 포인터를 배열로써 정의하여 사용할 수 있다.
함수의 경우 프로그램 메모리 영역 중의 code 영역에 속해 있다. 따라서 프로그램에서 함수를 호출한다는 것은 code 섹션의 해당 부분 명령어까지 jump하여 연산을 수행하는 것과 같다. 함수의 경우 프로그램 메모리 영역 중의 code 영역에 속해 있다. 따라서 프로그램에서 함수를 호출한다는 것은 code 섹션의 해당 부분 명령어까지 jump하여 연산을 수행하는 것과 같다.
##### 포인터 정리
```
int const A constant integer
int const * A (variable) pointer to a constant integer
int * const A constant pointer to a (variable) integer
int * const * A pointer to a constant pointer to an integer
int const * * A pointer to a pointer to a constant integer
int const * const * A pointer to a constant pointer to a constant integer
```
### c언어의 컴파일 과정 ### c언어의 컴파일 과정
<img src="./img/compile_process.PNG" width="550px" height="300px">
#### 컴파일 과정 #### 컴파일 과정
1. 전처리기에 의해 전처리 과정을 거친다. 1. 전처리기에 의해 전처리 과정을 거친다.
2. #define과 같은 전처리 인자를 모두 처리한 소스코드를 컴파일하여, 어셈블리 코드를 생성한다. 2. #define과 같은 전처리 인자를 모두 처리한 소스코드를 컴파일하여, 어셈블리 코드를 생성한다.
...@@ -305,6 +327,7 @@ gcc 머신 옵션을 통해 다른 아키텍처로도 컴파일을 할 수 있 ...@@ -305,6 +327,7 @@ gcc 머신 옵션을 통해 다른 아키텍처로도 컴파일을 할 수 있
* gcc -c hello.c : .o 파일 만들기 * gcc -c hello.c : .o 파일 만들기
* gcc -S hello.c : 어셈블리 언어까지 만들기 * gcc -S hello.c : 어셈블리 언어까지 만들기
* gcc -o hello.c : 실행파일 만들기 * gcc -o hello.c : 실행파일 만들기
* gcc -O hello.c : 최적화하기
전처리가 끝나면 .c 파일이 나온다. 전처리가 끝나면 .c 파일이 나온다.
...@@ -320,6 +343,17 @@ windows에서는 줄바꿈이 \r\n으로 구현되어 있지만 유닉스 기반 ...@@ -320,6 +343,17 @@ windows에서는 줄바꿈이 \r\n으로 구현되어 있지만 유닉스 기반
Cpp는 \를 매우 긴 문장을 한 줄로 붙여 준다. Cpp는 \를 매우 긴 문장을 한 줄로 붙여 준다.
Cpp는 모든 comments를 “”로 바꾸어 지운다. Cpp는 모든 comments를 “”로 바꾸어 지운다.
#### 최적화
최적화의 경우 다양한 방식이 존재한다. 아래는 최적화 단계의 목록이다.
* -O0(기본값) : 최적화를 수행하지 않는다.
* -O : 코드 크기와 실행 시간을 줄이는 것을 제외한 최적화는 실행하지 않는다.
* -O2 : 메모리 공간과 속도를 희생하지 않는 범위내의 모든 최적화를 수행한다. loop unrolling과 function inlining에 대한 최적화를 수행하지 않는다.
* -O3 : O2 최적화에 인라인 함수와 레지스터에 대한 최적화를 추가로 수행한다.
* -Os :-O2 최적화 기능을 사용하지만, 코드 크기를 증가시키는 최적화는 생략한다.
## Lecture 09 ## Lecture 09
### CPU & Floating point ### CPU & Floating point
...@@ -361,7 +395,18 @@ gdb a.out ...@@ -361,7 +395,18 @@ gdb a.out
프로그램은 로컬리티가 존재한다. 즉, 메모리에서 인접하게 위치한 데이터를 연산에 사용하는 것이 성능이 좋다. 메모리에 있는 데이터들을 CPU의 캐쉬에 가져오는데 이때 블록단위로 데이터를 가져온다. 만약에 서로 떨어진 데이터를 사용한다면 캐쉬에 메모리를 넣고 빼는 것을 반복하기 때문에 성능이 낮아진다. 프로그램은 로컬리티가 존재한다. 즉, 메모리에서 인접하게 위치한 데이터를 연산에 사용하는 것이 성능이 좋다. 메모리에 있는 데이터들을 CPU의 캐쉬에 가져오는데 이때 블록단위로 데이터를 가져온다. 만약에 서로 떨어진 데이터를 사용한다면 캐쉬에 메모리를 넣고 빼는 것을 반복하기 때문에 성능이 낮아진다.
명령어들은 CPU에서 파이프라인으로 동작하여 성능을 높이게 된다. 하지만 파이프라인은 조건문과 같은 브랜치를 만나면 진행 중인 파이프라인의 흐름이 끊길 수 밖에 없다. 따라서 if문과 같은 브랜치를 자주 사용한다면 프로그램의 성능이 낮아지게 된다. #### Pipeline
<img src="./img/pipeline.PNG">
명령어들은 CPU 내에서 아래와 같은 과정을 거친다.
1. fetch : 다음에 실행할 명령어를 메모리에서 읽어온다.
2. decoede : 명령어를 해석하여 다음에 어떠한 작업을 수행할 것인지 확인한다.
3. execute : 해석한 명령어를 바탕으로 작업을 수행한다.
4. memory : 작업을 수행하기 위해 메모리에 접근한다.
5. write : 작업의 결과물을 저장한다.
다만 하나의 명령어가 위의 5가지 과정을 모두 거쳐야 다른 명령어를 수행할 수 있는 것은 아니다. 예를 들어 A라는 명령 작업이 fetch를 마치고 decode 과정을 진행할 때 fetch를 대기 중인 작업 B가 이어서 fetch를 진행할 수 있다. 이렇듯 명령어들은 CPU에서 파이프라인으로 동작하여 CPU의 성능을 높일 수 있다. 하지만 파이프라인은 조건문과 같은 브랜치를 만나면 진행 중인 파이프라인의 흐름이 끊길 수 밖에 없다. 따라서 if문과 같은 브랜치를 자주 사용한다면 프로그램의 성능이 낮아지게 된다.
I/O도 역시 성능이 좋지 않기 때문에 printf와 같은 입출력 함수를 자주 사용한다면 성능이 좋지 않다. I/O도 역시 성능이 좋지 않기 때문에 printf와 같은 입출력 함수를 자주 사용한다면 성능이 좋지 않다.
...@@ -434,14 +479,24 @@ gccmakedep main.c fx_s_15_16.c ...@@ -434,14 +479,24 @@ gccmakedep main.c fx_s_15_16.c
* $@ : 타겟 파일을 의미한다. * $@ : 타겟 파일을 의미한다.
* $^ : 모든 dependency 파일들을 의미한다. * $^ : 모든 dependency 파일들을 의미한다.
* $< : dependency 파일들 중에서 가장 앞에 있는 파일을 의미한다. * $< : dependency 파일들 중에서 가장 앞에 있는 파일을 의미한다.
<img src="./img/macro_var.PNG">
이 외에도 수많은 변수 매크로가 존재한다. 또한 어셈블러, 컴파일러 등을 선택하는 여러 옵션들 또한 존재한다. 이 외에도 수많은 변수 매크로가 존재한다. 또한 어셈블러, 컴파일러 등을 선택하는 여러 옵션들 또한 존재한다.
아래의 사진은 어셈블러와, 컴파일러 등을 설정하는 옵션을 보여준다.
<img src="./img/macro_as.PNG">
### Cmake
CMake을 사용하기 위해서는 CMakeLists.txt 파일을 작성해야 한다.
CMakeLists.txt 파일을 작성한 후 터미널에 cmake 명령어를 입력하면 Makefile이 완성되어 make를 통한 컴파일이 가능하다.
## Lecture 13 ## Lecture 13
### 프로세스 ### 프로세스
<img src="./img/core.PNG">
CPU는 여러 코어들로 구성이 되어 있다. 코어는 실제로 프로세스를 진행하는 요소들이다. 따라서코어가 여러 개라면 CPU가 여러 개 있는 것과 같다. 일부 코어들끼리는 캐시를 공유하여 사용한다. 작업(job) 하나는 하나의 코어에서 실행 가능하다. 각각의 작업 단위를 프로세스라고 하는데 코어들은 이러한 작업 프로세스를 수행한다는 점에서 프로세서라고 부른다. CPU는 위의 사진과 같이 여러 코어들로 구성이 되어 있다. 코어는 실제로 프로세스를 진행하는 요소들이다. 따라서코어가 여러 개라면 CPU가 여러 개 있는 것과 같다. 일부 코어들끼리는 캐시를 공유하여 사용한다. 작업(job) 하나는 하나의 코어에서 실행 가능하다. 각각의 작업 단위를 프로세스라고 하는데 코어들은 이러한 작업 프로세스를 수행한다는 점에서 프로세서라고 부른다.
프로그램 코드들은 스토리지에 저장되어 있으며 프로그램이 실행될 때 메모리에 적재된다. 그리고 메모리에 적재된 프로그램들은 프로세스 형태로 존재하게 된다. 프로세스들은 두가지로 구분될 수 있는데, 하나는 OS의 프로세스인 system process이고 나머지 일반 프로그램들은 user process이다. 프로그램 코드들은 스토리지에 저장되어 있으며 프로그램이 실행될 때 메모리에 적재된다. 그리고 메모리에 적재된 프로그램들은 프로세스 형태로 존재하게 된다. 프로세스들은 두가지로 구분될 수 있는데, 하나는 OS의 프로세스인 system process이고 나머지 일반 프로그램들은 user process이다.
...@@ -450,6 +505,7 @@ CPU는 여러 코어들로 구성이 되어 있다. 코어는 실제로 프로 ...@@ -450,6 +505,7 @@ CPU는 여러 코어들로 구성이 되어 있다. 코어는 실제로 프로
ps 명령어는 현재 동작 중인 프로세스를 보여준다. 현재 실행 중인 프로세스의 이름과 함께 프로세스 ID 등이 표시된다. ps 명령어는 현재 동작 중인 프로세스를 보여준다. 현재 실행 중인 프로세스의 이름과 함께 프로세스 ID 등이 표시된다.
#### 프로세스 상태 #### 프로세스 상태
<img src="./img/process_state.PNG">
프로세스는 크게 run, kill(idle), stop 상태로 구분될 수 있다. run의 경우 foreground와 background 두개의 상태로 구분할 수 있다. 리눅스에서는 ctrl-z를 통해 현재 작업 중인 상태를 Stop 상태로 만들 수 있다. 그리고 stop된 프로세스를 fg 명령어를 통해 다시 run 상태로 바꿀 수 있다. 프로세스는 크게 run, kill(idle), stop 상태로 구분될 수 있다. run의 경우 foreground와 background 두개의 상태로 구분할 수 있다. 리눅스에서는 ctrl-z를 통해 현재 작업 중인 상태를 Stop 상태로 만들 수 있다. 그리고 stop된 프로세스를 fg 명령어를 통해 다시 run 상태로 바꿀 수 있다.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment