ELT API를 사용한 프로파일링
추적 프로파일러는 함수 시작과 종료를 기록하며 기록 호출 그래프를 유지할 수도 있습니다. .NET Framework에서는 이 기능을 구현할 수 있도록 프로파일링 전역 정적 함수를 제공하며, 이러한 함수에는 ELT(Enter/Leave/Tailcall) API라고 하는 관련 함수 및 인터페이스 집합이 포함되어 있습니다.
.NET Framework 버전 4 이전 버전에서 ELT 함수를 사용한 추적 프로파일러는 작은 관리되는 함수의 수가 증가함에 따라 성능상 부담이 늘어나는 단점이 있었습니다. .NET Framework 4부터는 특히 인수 또는 반환 값 검사가 필요하지 않은 경우에 ELT 버전 3(ELT3) API를 사용하여 ELT 성능을 개선할 수 있습니다. 구체적인 성능 향상 내용은 다음과 같습니다.
ELT 빠른 경로 함수에 대한 just-in-time 컴파일된 코드의 크기가 줄어듭니다.
필요한 ELT 인수의 수가 최소로 줄어들므로 프로파일러로 전달되는 매개 변수에 필요한 스택 공간이 감소합니다.
스택 프레임 설정 및 인수 검사는 필요한 경우에만 수행되므로 실행 속도가 향상됩니다.
새 ICorProfilerInfo3 메서드가 호출될 경우 프레임 및 인수 정보의 초기화가 지연됩니다.
ELT3 인터페이스는 .NET Framework의 이전 버전에 있는 인터페이스(ELT1 및 ELT2)와 호환됩니다.
.NET Framework 4에서는 ELT3을 기반으로 ELT2 함수를 구현하고 추가적인 해시 테이블을 사용하여 클라이언트 ID와 함수 ID를 매핑합니다. 따라서 ELT2 함수를 사용할 경우 상당한 동기화 비용이 발생하고 프로파일링 속도가 저하됩니다. 부하가 많이 걸리는 다중 프로세서 컴퓨터에서는 더욱 크게 성능이 저하됩니다. 이에 비해 프로파일러를 ELT3 API로 마이그레이션하는 코드 변경은 간단하고 비용이 적게 들기 때문에 최상의 성능을 위해 ELT3을 채택하는 것이 좋습니다.
ELT3 함수 및 메서드
ELT3 API에서는 세 가지 유형의 멤버를 제공합니다.
알림 함수. 이 함수는 대상 응용 프로그램의 함수로 제어가 전달되고 있음을 프로파일러에게 알리기 위해 CLR에서 호출됩니다.
등록 메서드. 이 메서드는 빠른 경로 또는 느린 경로 검사 메서드를 사용하기 위해 프로파일러에서 호출됩니다.
검사 메서드. 이 메서드는 인수 또는 반환 값 정보를 검색하기 위해 프로파일러에서 호출됩니다.
ELT3 알림 함수
.NET Framework 4부터는 ELT3 알림 함수 6개 중 3개를 사용하여 대상 응용 프로그램, 즉 프로파일링되는 응용 프로그램의 함수로 제어가 전달되고 있음을 프로파일러에게 알릴 수 있습니다. ELT3 알림 함수는 빠른 경로 함수 및 느린 경로 함수로 구성되어 있습니다.
빠른 경로 함수는 중간 코드 없이 프로파일러의 ELT 메서드를 직접 호출하는 JIT 컴파일된 코드로 규정됩니다.
느린 경로 함수는 프로파일러의 ELT 메서드를 실제로 호출하기 전에 중간 코드(CLR DLL로 컴파일되는 C 코드와 어셈블리 코드의 조합이 대부분임)를 호출하는 JIT 컴파일된 코드로 규정됩니다.
다음 세 가지 함수는 빠른 경로 함수이며, 이러한 함수에 필요한 매개 변수는 함수 식별자, 즉 제어가 전달되거나 반환되는 함수 또는 마무리 호출을 수행하려는 함수의 식별자입니다.
다음 세 가지 함수는 느린 경로 함수이며, 이러한 함수에 필요한 매개 변수로는 함수 식별자 외에 스택 프레임 관련 정보에 대한 핸들이 있습니다.
이 세 함수에서 런타임이 프로파일러에 전달하는 두 번째 매개 변수(eltInfo)는 스택에 있는 _COR_PRF_ELT_INFO_INTERNAL 구조체에 대한 불투명 포인터입니다. 이 구조체는 ELT 어셈블리 도우미에서 생성하는 플랫폼별 핸들을 포함합니다. 프로파일러는 ICorProfilerInfo3::GetFunctionEnter3Info, ICorProfilerInfo3::GetFunctionLeave3Info 및 ICorProfilerInfo3::GetFunctionTailcall3Info 메서드에서 eltInfo 포인터를 사용할 수 있습니다.
ELT3 등록 메서드
다음 두 가지 ELT3 등록 메서드를 사용하여 느린 경로 ELT 함수 및 빠른 경로 ELT 함수를 설정할 수 있습니다.
이러한 메서드 중 하나는 응용 프로그램 시작 시 프로파일러의 ICorProfilerCallback::Initialize 또는 ICorProfilerCallback3::InitializeForAttach 콜백에서 호출되어야 합니다. 프로파일러는 SetEventMask를 사용하여 원하는 이벤트 플래그를 등록한 후 SetEnterLeaveFunctionHooks3 메서드를 호출하여 빠른 경로 ELT3을 사용하거나 SetEnterLeaveFunctionHooks3WithInfo 메서드를 호출하여 느린 경로 ELT3을 사용해야 합니다.
빠른 경로 ELT3 후크는 느린 경로 ELT3 후크와 함께 사용될 수 없고, ELT3 후크는 ELT1 또는 ELT2 후크와 함께 사용될 수 없습니다. SetEnterLeaveFunctionHooks3 또는 SetEnterLeaveFunctionHooks3WithInfo를 호출하기 전에 느린 경로를 요구하는 적절한 이벤트 플래그(COR_PRF_ENABLE_FUNCTION_ARGS, COR_PRF_ENABLE_FUNCTION_RETVAL 또는 COR_PRF_ENABLE_FRAME_INFO)를 프로파일러에서 지정하지 않은 경우 CORPROF_E_INCONSISTENT_WITH_FLAGS 오류 코드가 반환되어 실패를 나타냅니다.
ELT3 검사 메서드
ELT3 알림 함수에서는 인수 또는 반환 값 정보를 제공하지 않기 때문에 프로파일러는 다음 ICorProfilerInfo3 검사 메서드 중 하나를 호출하여 원하는 정보를 명시적으로 요청해야 합니다.
이러한 메서드는 해당하는 느린 경로 ELT3 함수(FunctionEnter3WithInfo, FunctionLeave3WithInfo 및 FunctionTailcall3WithInfo)의 프로파일러 구현에서 호출되어야 하며 프로파일러는 ELT 알림 함수로부터 받은 eltInfo 값을 제공해야 합니다. ELT3 검사 메서드를 ELT3 빠른 경로 알림 함수(FunctionEnter3, FunctionLeave3, FunctionTailcall3)의 프로파일러 구현에서 호출하거나 ELT1 또는 ELT2 알림 함수에서 호출할 수 없다는 점에 유의하십시오.