싱글 스레드 빌드

싱글 스레드 빌드

Zig는 -fsingle-threaded라는 컴파일 옵션을 제공하는데요, 이 옵션을 켜면 다음과 같은 효과가 생겨요.

  • 모든 Thread Local Variables를 일반적인 Namespace Level Variables로 취급해요.
  • Async Functions의 오버헤드가 일반 함수 호출 오버헤드 수준으로 줄어들어요.
  • @import("builtin").single_threadedtrue가 돼요. 그래서 이 변수를 읽는 여러 사용자 영역(userland) API가 더 효율적으로 동작하죠. 예를 들어 std.Mutex는 빈 데이터 구조가 되고, 그 함수들은 전부 no-op이 되어요.

출처: Zig Documentation

본문

-fsingle-threaded는 프로그램이 단일 스레드로 동작한다는 사실을 컴파일러에 알려주는 옵션이에요. 단일 스레드 환경에서는 한 번에 하나의 실행 흐름만 존재하니까, 원래라면 스레드마다 따로 관리해야 할 것들을 일반 변수 취급하거나 그 보호 장치를 통째로 생략해도 안전해져요.

그래서 결과적으로 이 옵션은 '안전을 위한 장치를 덜어내는' 방향으로 작동해요. Thread Local Variables를 일반 변수로 취급한다는 건, 스레드별 저장 공간을 나누지 않는다는 뜻이고, Async Functions의 오버헤드가 줄어든다는 건, 동시 실행을 위해 챙겨야 했던 부가 비용이 사라진다는 뜻이죠.

세 번째 항목을 좀 더 살펴볼게요. @import("builtin").single_threaded는 빌드 모드가 단일 스레드인지 알려주는 플래그인데, 이 값이 true가 되면 이걸 읽는 라이브러리들이 자기 로직을 단순화할 수 있어요. 대표적인 예가 std.Mutex예요. 멀티 스레드 환경에서는 락(lock)을 걸고 푸는 실제 동작이 필요하지만, 실행 흐름이 하나뿐이라면 경쟁 자체가 일어날 수 없으니까 락을 걸 이유가 없어요. 그래서 Zig는 이 경우 std.Mutex를 빈 구조체로 만들고 모든 함수를 no-op으로 바꿔서, 아무 일도 하지 않는 대신 아무 비용도 들지 않게 만드는 거죠.

더 알아보기