일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Flash Memory
- 키워드
- overflow
- Git
- Intel
- USENIX
- hardware
- deep learning
- 커널 프로그래밍
- Machine Learning
- performance
- Cache
- kernel
- FTL
- 시스템 프로그래밍
- github
- 시스템 소프트웨어
- memory
- storage system
- Operating System
- core dumped
- 포트 번호 변경
- framework
- ssd
- linux
- rocksdb
- software
- Samsung
- Today
- Total
Happy to visit my research note ^^
kernel 개발에 필요한 키워드 정리 (c lang) 본문

kernel에 대한 간략한 소개를 하자면, kernel은 운영체제의 핵심 부분으로, 하드웨어와 소프트웨어 간의 interface 역할을 한다. kernel은 컴퓨터 resource를 관리하고 응용 프로그램이 application이 하드웨어를 직접 제어하는 것을 마고, 시스템 resource에 대한 효율적인 접근을 가능하게 한다. 또한, kernel은 사용자와 하드웨어 간의 상호작용을 처리하며, 시스템의 안정성과 보안을 유지하기 위한 여러 기능을 제공한다. 즉, 운영체제의 핵심이라고 할 수 있습니다.
이러한 kernel을 개발을 할 때 사용되는 알아두면 편리한 각 keyword에 대해 이번 글에서 알아볼까 합니다.
" inline keyword "
W(저자)가 사용하는 c lang에서 inline 키워드는 함수를 인라인으로 치환해서 함수 호출의 오버헤드를 줄이기 위해 사용된다.
inline 함수는 함수의 코드를 함수 호출 지점에 복사해서, 호출이 아니라 해당 위치에서 함수의 코드가 실행되도록 한다. 이를 통해서 함수 호출의 오버헤드를 줄이고 성능을 향상할 수 있다고 함..
inline 함수는 컴파일러가 inline 함수를 치환할지 여부를 결정하기 때문에, 실제로 inline 함수로 치환되지 않을 수도 있다.
컴파일러가 inline 함수로 치환을 결정하는 기준은 구현에 따라 다르다.
-> 함수의 크기나 복잡도, 호출 빈도 등이 고려되고 각 컴파일러의 최적화 옵션에 따라 다르다.
일반적으로는 짧은 함수에 대해 inline 치환을 하기 쉬운데 이 짧음의 기준을 보통 10라인 정도인 경우 성능상의 이점을 가져올 수 있다고 한다. 그러나 함수 크기보다도 호출 빈도가 높은 함수인 경우 inline 치환의 하는 것이 좋다.
짧음을 기준으로 둔다면 모든 짧은 함수에 넣으면 되지 않는가에 대한 궁금증을 일으켰었는데 그것보다는 해당 함수가 성능상 이점을 가져올 수 있느지 ( 함수의 호출 빈도 ) 고려하여 결정하는 것이 현명하다.
" extern keyword "
extern keyword는 변수나 함수를 선언할 때 사용되며, 이것이 선언되는 파일에서는 정의하지 않고 다른 파일에서 정의하도록 선언함으로써 다른 파일에서 사용 가능하도록 만드는 역할을 한다.
예시로는, 여러 개의 소스 파일이 하나의 헤더 파일을 공유하는 경우가 있습니다. 이때 헤더 파일에서 extern 키워드를 사용하여 다른 파일에서 정의된 변수나 함수를 사용할 수 있도록 만들 수 있습니다.
[ count.h ]
#ifndef COUNT_H
#define COUNT_H
extern int count;
#endif // COUNT_H
[ main.c ]
#include "count.h"
#include <stdio.h>
int count = 0;
void foo();
int main() {
count++;
printf("count in main.c before foo(): %d\n", count);
foo();
printf("count in main.c after foo(): %d\n", count);
return 0;
}
[ foo.c ]
#include "count.h"
#include <stdio.h>
void foo() {
count++;
printf("count in foo.c: %d\n", count);
}
[ 실행 결과 ]
count in main.c before foo(): 1
count in foo.c: 2
count in main.c after foo(): 2
위 예시에서는 count.h 파일에서 extern 키워드를 사용하여 이렇게 하면 count.h 헤더 파일을 include 한 다른 파일에서 이 변수와 함수를 사용할 수 있습니다.
header file에 정의되어있는 extern int count 변수는 main에서 선언하여 사용하면 foo.c에 값이 공유됩니다.
만약 main.c에서 int count = 0 ; 으로 선언을 하고 나서 다른 파일에서 한번 더 선언을 하게 될 시에 "multiple definition" 에러가 일어날 수 있으므로 주의해야 합니다.
call path는 main에서 정의 값(1) -> foo 루틴 타면서 값(2) -> main으로 돌아와서 값(2)이 유지된 상태에서 출력되는 것을 볼 수 있습니다.
+ 참고
함수의 경우, 선언만 헤더파일에 놓으면 다른 파일에서도 그 함수를 사용할 수 있다. 이 경우, 함수의 정의는 다른 소스 파일에서 한번 더 선언하게 된다. 따라서, " extern " 키워드를 함수에 붙이지 않아도 되며, 오히려 붙이면 에러가 발생할 수 있다.
즉, 변수의 경우에는 선언과 정의를 분리하여 사용하기 때문에 " extern " 키워드를 붙여야 하지만, 함수는 선언과 정의가 항상 함께하기 때문에 " extern " 키워드를 붙일 필요가 없다.
즉, extern keyword는 변수가 선언된 파일 외부에서 이미 정의된 변수를 사용하겠다는 의미여서, 여러 소스 파일에서 extern을 선언하면 모두 같은 변수를 가리키게 됩니다. 고로, 이 변수의 값을 변경하면 다른 소스 파일에서도 변경된 값을 참조할 수 있습니다.
주의할 점은 어디서 변수 값이 변경될 수 있는지를 체크해야 하며, 가능하면 전역 변수 사용을 최소화하는 것이 좋습니다.
" const keyword "
const keyword는 변수를 상수로 만드는 키워드이다. const로 정의된 변수는 값을 변경할 수 없다.
예를 들어, 다음과 같이 const로 선언된 변수는 값을 변경할 수 없습니다.
const int a = 10;
a = 20; // 오류 발생
함수에서도 const를 사용할 수 있다. 이 경우 함수가 매개변수로 전달받은 변수를 변경하지 않겠다는 의미입니다.
void print_value(const int num) {
// num = 20; // 오류 발생
printf("num: %d\n", num);
}
const keyword의 주된 목적은 보안 및 프로그램의 안정성을 높이기 위해 사용됩니다. 함수에서 매개변수로 전달받은 값을 변경하지 않으면 프로그램이 예기치 않게 동작하는 것을 방지할 수 있습니다. 또한, const로 정의된 변수를 사용하면 코드의 가독성을 높일 수 있습니다.
const와 비슷하게는 #define을 이용한 전처리기를 사용하는 방법이 있습니다.
차이점에 대한 설명으로는
1. 데이터 타입의 검사 여부
const는 데이터 타입을 지정해야 하므로 컴파일러가 상수에 대한 데이터 타입을 검사합니다. #define은 단순히 문자열 치환을 수행하므로 데이터 타입 검사가 이루어지지 않습니다.
2. 유효범위
const는 변수와 마찬가지로 블록 scope를 갖습니다. #define은 전처리기가 수행하므로 파일 전체에서 유효합니다.
3. 디버깅
const는 디버깅이 용이합니다. 디버거는 변수가 읽기 전용임을 알고 있으므로 상수 값을 변경할 수 없도록 보호한다. #define은 디버거에 의해 치환되므로 디버깅에 어려움이 있을 수 있다.
이 경우들을 미루어봤을 때, const가 #define보다 안전하고 유지보수가 쉬우며, 타입 검사가 필요한 경우 const를 사용하는 것이 좋다고 생각합니다.
" static keyword "
커널 프로그래밍에서 ' static ' 키워드는 변수 또는 함수를 정의할 때 사용된다.
이 키워드는 해당 변수 또는 함수를 선언한 파일 내에서만 사용 가능하도록 만듭니다.
kernel에서 함수를 정의할 때 static 키워드를 사용하는 경우가 많은 이유는 크게 두 가지로 나누어본다.
첫째, static 함수는 컴파일러에 의해 해당 함수가 선언된 파일 내에서만 사용 가능하도록 제한된다. 따라서, 다른 파일에서 해당 함수를 호출하는 것을 방지할 수 있다. 이것은 global namespace를 오염시키지 않아서 code maintenance와 stability를 향상할 수 있다.
둘째, static 함수는 다른 파일에서 호출되지 않으므로, 함수 호출 시 발생하는 오버헤드가 없어져서 실행 시간이 빨라질 수 있다. 이는 특히 커널 내에서 자주 호출되는 함수에서 유용하다. 고로! static 키워드를 사용하여 함수를 정의하는 것은 compiler optimization과 code maintenance에 좋은 방법이다.
static을 전역 변수로 썼을 때와 지역 변수로 썼을 때는
전역 변수로 선언했을 시에
- 해당 파일 내에서만 사용 가능하며, 다른 파일에서 접근할 수 없다. 따라서, 이름이 같은 변수가 다른 파일에 존재하더라도 서로 영향을 미치지 않는다.
지역 변수로 선언했을 시에
- 지역 변수로 선언된 static 변수는 해당 함수 내에서만 사용 가능하며, 다른 함수에서는 접근할 수 없다. 이는 변수가 선언된 함수가 호출될 때마다 생성되고 함수가 반환될 때 소멸되는 지역 변수의 특징과는 조금 다르다. static 변수는 함수가 호출될 때 생성되며, 프로그램이 종료될 때까지 메모리에 유지됩니다. 이는 변수가 선언된 함수가 호출될 때마다 생성되지 않고, 따라서 값이 유지된다는 의미입니다.
따라서, static 변수는 함수의 호출과 무관하게 값을 유지하고 싶을 때, 혹은 한 파일 내에서만 사용하고 싶을 때 유용하게 사용하면 됩니다!!
+ 참고
함수의 선언은 함수가 존재한다는 것을 컴파일러에게 알리는 역할을 한다. 함수의 이름, 인자의 개수, 자료형 등 함수에 대한 정보를 컴파일러에게 알려준다. 함수 선언만 한 경우, 컴파일러는 해당 함수가 어디에 있는지 모르기 때문에 함수가 호출될 때 링커에서 해당 함수를 찾아 링크한다.
함수의 정의는 함수를 구현하는 역할을 한다. 함수의 선언과는 달리, 함수의 몸체를 구현한다. 함수를 정의하는 파일에서는 반드시 해당 함수를 선언해야 한다. 함수를 호출하는 파일에서는 해당 함수를 선언만 하면 된다.
'Kernel & Linux programming with C Lang' 카테고리의 다른 글
내가 쓰는 파일 입출력에 대한 간단한 정리 (0) | 2023.02.28 |
---|---|
linux에서 buffer에 timestamp를 찍기를 원할 때 알면 좋은 것들 (0) | 2023.02.22 |
kernel에서 함수 정의 시 static 키워드를 자주 사용하는 이유 (0) | 2023.02.22 |
상/하위 레이어 함수 간의 코드를 공유하는 방법 (0) | 2023.02.22 |
sprintf 와 printk의 차이 (0) | 2023.02.16 |