System Image Building
Building the Julia system image
Julia는 Base
모듈의 내용을 포함하는 준비된 시스템 이미지를 sys.ji
라는 이름으로 제공합니다. 이 파일은 가능한 많은 플랫폼에서 sys.{so,dll,dylib}
라는 공유 라이브러리로도 미리 컴파일되어 있어 시작 시간을 크게 개선합니다. 미리 컴파일된 시스템 이미지 파일이 제공되지 않는 시스템에서는 Julia의 DATAROOTDIR/julia/base
폴더에 포함된 소스 파일에서 생성할 수 있습니다.
줄리아는 기본적으로 사용 가능한 시스템 스레드의 절반에서 시스템 이미지를 생성합니다. 이는 JULIA_IMAGE_THREADS
환경 변수를 통해 제어할 수 있습니다.
이 작업은 여러 가지 이유로 유용합니다. 사용자는:
- 프리컴파일된 공유 라이브러리 시스템 이미지를 제공하지 않는 플랫폼에서 이를 구축하여 시작 시간을 개선합니다.
Base
를 수정하고 시스템 이미지를 재구성한 후, 다음 번에 Julia를 시작할 때 새로운Base
를 사용하세요.userimg.jl
파일을 포함하여 패키지를 시스템 이미지에 포함시켜, 시작 환경에 패키지가 내장된 시스템 이미지를 생성합니다.
PackageCompiler.jl
package는 이 프로세스를 자동화하는 편리한 래퍼 함수를 포함하고 있습니다.
System image optimized for multiple microarchitectures
시스템 이미지는 동일한 명령어 집합 아키텍처(ISA) 하에서 여러 CPU 마이크로아키텍처를 위해 동시에 컴파일될 수 있습니다. 서로 다른 ISA 확장 또는 기타 마이크로아키텍처 기능을 활용하기 위해 최소 디스패치 포인트가 공유 함수에 삽입된 동일한 함수의 여러 버전이 생성될 수 있습니다. 최상의 성능을 제공하는 버전은 사용 가능한 CPU 기능에 따라 런타임에서 자동으로 선택됩니다.
Specifying multiple system image targets
다중 마이크로아키텍처 시스템 이미지는 시스템 이미지 컴파일 중 여러 대상을 전달하여 활성화할 수 있습니다. 이는 JULIA_CPU_TARGET
메이크 옵션을 사용하거나 수동으로 컴파일 명령을 실행할 때 -C
명령줄 옵션을 사용하여 수행할 수 있습니다. 여러 대상은 옵션 문자열에서 ;
로 구분됩니다. 각 대상의 구문은 CPU 이름 뒤에 여러 기능이 ,
로 구분되어 나열됩니다. LLVM에서 지원하는 모든 기능이 지원되며, 기능은 -
접두사를 사용하여 비활성화할 수 있습니다. (+
접두사도 허용되며 LLVM 구문과 일관성을 유지하기 위해 무시됩니다). 또한, 함수 복제 동작을 제어하기 위해 몇 가지 특별한 기능이 지원됩니다.
모든 타겟에 대해 첫 번째 타겟을 제외하고는 clone_all
또는 base(<n>)
중 하나를 지정하는 것이 좋은 관행입니다. 이렇게 하면 모든 함수가 복제된 타겟과 다른 타겟을 기반으로 하는 타겟이 명확해집니다. 이를 수행하지 않으면 기본 동작은 모든 함수를 복제하지 않고, 함수를 복제하지 않을 때 첫 번째 타겟의 함수 정의를 대체로 사용하는 것입니다.
clone_all
기본적으로, 마이크로아키텍처 기능의 혜택을 가장 많이 받을 가능성이 있는 함수만 복제됩니다. 그러나 대상에 대해
clone_all
이 지정되면 시스템 이미지의 모든 함수가 해당 대상에 대해 복제됩니다. 내장된 휴리스틱이 모든 함수를 복제하는 것을 방지하기 위해-clone_all
의 부정형을 사용할 수 있습니다.base(<n>)
여기서
<n>
은 비음수 숫자에 대한 자리 표시자입니다 (예:base(0)
,base(1)
). 기본적으로 부분적으로 복제된 (즉,clone_all
이 아닌) 대상은 복제되지 않은 함수에 대해 기본 대상(첫 번째로 지정된 대상)의 함수를 사용합니다. 이 동작은base(<n>)
옵션으로 다른 기본 대상을 지정하여 변경할 수 있습니다.n
번째 대상(0부터 시작)은 기본 대상 대신 기본 대상(0
번째)으로 사용됩니다. 기본 대상은0
이거나 다른clone_all
대상이어야 합니다. 비clone_all
대상을 기본 대상으로 지정하면 오류가 발생합니다.opt_size
이것은 실행 시간 성능에 큰 영향을 미치지 않을 때 대상 함수의 크기를 최적화하도록 합니다. 이는
-Os
GCC 및 Clang 옵션에 해당합니다.최소_크기
이로 인해 대상 함수가 크기를 최적화하도록 설정되어 실행 시간 성능에 상당한 영향을 미칠 수 있습니다. 이는
-Oz
Clang 옵션에 해당합니다.
예를 들어, 이 글을 작성하는 시점에서, julialang.org에서 다운로드할 수 있는 공식 x86_64
Julia 바이너리 생성에 사용되는 문자열은 다음과 같습니다:
generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)
이것은 세 개의 개별 타겟을 가진 시스템 이미지를 생성합니다. 하나는 일반 x86_64
프로세서를 위한 것이고, 하나는 xsaveopt
를 명시적으로 제외한 sandybridge
ISA를 위한 것이며, 모든 함수를 명시적으로 복제합니다. 마지막으로 sandybridge
sysimg 버전을 기반으로 하여 rdrnd
도 제외한 haswell
ISA를 타겟으로 하는 것이 있습니다. Julia 구현이 생성된 sysimg를 로드할 때, 호스트 프로세서의 CPU 기능 플래그를 확인하여 가능한 가장 높은 ISA 레벨을 활성화합니다. 기본 레벨(generic
)은 cx16
명령어를 요구하는데, 이는 일부 가상화 소프트웨어에서 비활성화되어 있으며 generic
타겟이 로드되기 위해서는 활성화되어야 합니다. 또는 더 큰 호환성을 위해 generic,-cx16
타겟으로 sysimg를 생성할 수 있지만, 이는 일부 코드에서 성능 및 안정성 문제를 일으킬 수 있습니다.
Implementation overview
이것은 구현에 관련된 다양한 부분에 대한 간략한 개요입니다. 각 구성 요소에 대한 더 많은 구현 세부정보는 코드 주석을 참조하십시오.
시스템 이미지 컴파일
파싱 및 클로닝 결정은
src/processor*
에서 이루어집니다. 현재 우리는 루프, SIMD 명령어 또는 기타 수학 연산(예: fastmath, fma, muladd)의 존재에 따라 함수 클로닝을 지원합니다. 이 정보는 실제 클로닝을 수행하는src/llvm-multiversioning.cpp
로 전달됩니다. 클로닝을 수행하고 디스패치 슬롯을 삽입하는 것(어떻게 수행되는지는MultiVersioning::runOnModule
의 주석을 참조) 외에도, 이 패스는 런타임이 시스템 이미지를 올바르게 로드하고 초기화할 수 있도록 메타데이터를 생성합니다. 메타데이터에 대한 자세한 설명은src/processor.h
에서 확인할 수 있습니다.시스템 이미지 로딩
시스템 이미지의 로딩 및 초기화는 시스템 이미지 생성 중 저장된 메타데이터를 파싱하여
src/processor*
에서 수행됩니다. 호스트 기능 감지 및 선택 결정은 ISA에 따라src/processor_*.cpp
에서 이루어집니다. 대상 선택은 정확한 CPU 이름 일치, 더 큰 벡터 레지스터 크기 및 더 많은 기능을 우선시합니다. 이 과정에 대한 개요는src/processor.cpp
에 있습니다.