1.2 A Minimal Kernel
컴파일 대상 환경 설정
{
"llvm-target": "x86_64-unknown-none", // 운영체제 대상
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"arch": "x86_64", // 컴파일 대상 ISA
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort", // stack unwinding 지원하지 않으므로 패닉시 즉시 종료
"disable-redzone": true, // red zone 스택 포인터 최적화 기능 해제 ->
"features": "-mmx,-sse,+soft-float" // 컴파일 대상 환경 기능등
}
disable-redzone
Red Zone
![[Pasted image 20231210103012.png]] n개의 지역 변수를 가진 함수 스택 포인터 함수가 호출되었을 때, 함수의 반호나 주소 및 지역변수들을 스택에 저장할 수 있게 스택포인터 값 조정 Red Zone은 조정된 스택 포인터아래의 128바이트 메모리 구간을 가르킨다. 함수가 또 다른 함수를 호출하지 않는 구간에서만 사용하는 임시 데이터의 경우, 함수가 이 구간에 해당 데이터를 저장하는데 이용될 수 있다. 따라서 스택 포인터를 조정하기 위해 필요한 명령어 두 개를 생략할 수 있는 상황이 종종 있다.( 다른 함수를 호출 하지 않는 함수)
하지만 이 최적화 기법을 사용하는 도중 exception 혹은 hardware intterupt가 일어날 경우 큰 문제가 생긴다. 함수가 red zone을 사용하는 도중 예외가 발생한 상황을 가정해보자
![[Pasted image 20231210104439.png]] CPU와 exception handler가 red zone에 있는 데이터를 덮어씁니다. 하지만 이 데이터는 interrupt된 함수가 사용중이다. 따라서 exception handler로 부터 반환되어 다시 interrupt 함수가 계속 실행하게 되었을때, 변경된 red zone의 데이터로 인해 함수가 오작동 할 수 있다. 이런 현상으로 인해 디버깅하는데 몇 주씩 걸리는 이상한 버그를 발생시킬수도 있다.
features : mmx, sse soft-float
Single Instruction Multiple Data(SIMD)
- CPU에서 지원되는 명령어 셋으로 하나의 명령어로 동일한 형태 / 구조의 여러 데이터를 한번에 처리하는 병렬처리기법
- x86/amd64
- MMX, SSE, SSE2, AVX, AVX2, AVX512F
- ARM
- N개의 32비트 정수 A,B 덧셈 연산을 하는 예시 (a) SISD(Single Instruction Single Data)
- 3개의 레지스터에 N번 연산 (b) SIMD(Single Instruction Multiple Data)
- 모든 변수를 한번에 처리 ```javascript // SISD var a = [1, 2, 3, 4]; var b = [5, 6, 7, 8]; var c = [];
c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; c[3] = a[3] + b[3]; c; // Array[6, 8, 10, 12]
// SIMD var a = SIMD.Float32x4(1, 2, 3, 4); var b = SIMD.Float32x4(5, 6, 7, 8); var c = SIMD.Float32x4.add(a,b); // Float32x4[6, 8, 10, 12]
행렬, 벡터 계산에 SIMD가 효율적. 따라서 그래픽 드라이버 DirectX, OpenGL은 SIMD를 지원
#### 구현 방법
- 어셈블리 / Intrinsic func(inline assembly match)
- 요즘 최신 컴파일러들은 자체적으로 SIMD instruction 사용한 코드로 변환해줌
#### Aligned memory
```c--
short a, b, c, d; // (1) Not aligned
short a[4]; // (2) Not Aligned
__declspec(align(32)) short a[4]; // (3) Aligned
![[Pasted image 20231210113627.png]] 메모리 시작 지점을 align 한 숫자들을 배수로 맞추고 내부 원소 하나하나의 크기를 align한 크기로 맞춤
Intrinsic Function
_mm_<intrin_op>_<suffix>
![[Pasted image 20231210114446.png]]
const int n = 1000000000;
__m128i a, b, r;
__declspec(align(16)) short v1[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
__declspec(align(16)) short v2[8] = { 8, 1, 7, 2, 6, 3, 5, 4 };
__declspec(align(16)) short result[8];
// SISD
for (int i = 0; i < n; ++i) {
result[0] = v1[0] > v2[0] ? v1[0] : v2[0];
result[1] = v1[1] > v2[1] ? v1[1] : v2[1];
result[2] = v1[2] > v2[2] ? v1[2] : v2[2];
result[3] = v1[3] > v2[3] ? v1[3] : v2[3];
result[4] = v1[4] > v2[4] ? v1[4] : v2[4];
result[5] = v1[5] > v2[5] ? v1[5] : v2[5];
result[6] = v1[6] > v2[6] ? v1[6] : v2[6];
result[7] = v1[7] > v2[7] ? v1[7] : v2[7];
}
// SIMD
for (int i = 0; i < n; ++i) {
a = _mm_loadu_si128((__m128i *)v1);
b = _mm_loadu_si128((__m128i *)v2);
r = _mm_max_epi16(a, b);
_mm_storeu_si128((__m128i *)result, r);
}
![[Pasted image 20231210114510.png]]
soft-float기능
일반 정수 계산만을 이용해 부동소수점 계산을 SW에서 모방