다음을 통해 공유


Interop에 대한 성능 고려 사항(C++)

이 항목에서는 런타임 성능에 대한 관리/관리되지 않는 interop 전환의 영향을 줄이기 위한 지침을 제공합니다.

Visual C++는 Visual Basic 및 C#(P/Invoke)과 같은 다른 .NET 언어와 동일한 상호 운용성 메커니즘을 지원하지만 Visual C++(C++ interop)와 관련된 interop 지원도 제공합니다. 성능에 중요한 애플리케이션의 경우 각 interop 기술의 성능 영향을 이해하는 것이 중요합니다.

사용되는 interop 기술에 관계없이 관리되는 함수가 관리되지 않는 함수를 호출할 때마다 thunks라고 하는 특수 전환 시퀀스가 필요하며 그 반대의 경우도 마찬가지입니다. 이러한 펑크는 Microsoft C++ 컴파일러에 의해 자동으로 삽입되지만, 누적적으로 이러한 전환은 성능 측면에서 비용이 많이 들 수 있다는 점을 명심해야 합니다.

전환 감소

interop thunks의 비용을 방지하거나 줄이는 한 가지 방법은 관리/관리되지 않는 전환을 최소화하기 위해 관련된 인터페이스를 리팩터링하는 것입니다. 관리/관리되지 않는 경계에서 자주 호출되는 대화형 인터페이스를 대상으로 하여 성능이 크게 향상될 수 있습니다. 예를 들어 타이트 루프에서 관리되지 않는 함수를 호출하는 관리되는 함수는 리팩터링에 적합한 후보입니다. 루프 자체가 관리되지 않는 쪽으로 이동되거나 관리되지 않는 호출에 대한 관리되는 대안이 만들어지는 경우(관리되는 쪽에서 데이터를 큐에 대기한 다음 루프 후에 관리되지 않는 API로 마샬링하는 경우) 전환 수를 크게 줄일 수 있습니다.

P/Invoke 및 C++ Interop

Visual Basic 및 C#과 같은 .NET 언어의 경우 네이티브 구성 요소와 상호 운용하기 위한 규정된 방법은 P/Invoke입니다. P/Invoke는 .NET Framework에서 지원되기 때문에 Visual C++도 지원하지만 Visual C++는 자체 상호 운용성 지원(C++ Interop이라고도 함)도 제공합니다. P/Invoke는 형식이 안전하지 않으므로 P/Invoke보다 C++ Interop이 선호됩니다. 결과적으로 오류는 주로 런타임에 보고되지만 C++ Interop에는 P/Invoke보다 성능 이점이 있습니다.

두 기술 모두 관리되는 함수가 관리되지 않는 함수를 호출할 때마다 몇 가지 작업이 필요합니다.

  • 함수 호출 인수는 CLR에서 네이티브 형식으로 마샬링됩니다.

  • 관리되는 관리되지 않는 thunk가 실행됩니다.

  • 관리되지 않는 함수가 호출됩니다(네이티브 버전의 인수 사용).

  • 관리되지 않는 관리되는 thunk가 실행됩니다.

  • 반환 형식과 "out" 또는 "in,out" 인수는 네이티브에서 CLR 형식으로 마샬링됩니다.

interop가 전혀 작동하려면 관리/관리되지 않는 펑크가 필요하지만 필요한 데이터 마샬링에는 관련된 데이터 형식, 함수 서명 및 데이터 사용 방법에 따라 달라집니다.

C++ Interop에서 수행하는 데이터 마샬링이 가능한 가장 간단한 형태입니다. 매개 변수는 단순히 관리/관리되지 않는 경계를 가로질러 비트 방식으로 복사됩니다. 변환이 전혀 수행되지 않습니다. P/Invoke의 경우 모든 매개 변수가 단순하고 Blittable 형식인 경우에만 true입니다. 그렇지 않으면 P/Invoke는 관리되는 각 매개 변수를 적절한 네이티브 형식으로 변환하는 매우 강력한 단계를 수행하고, 인수가 "out" 또는 "in,out"으로 표시된 경우 그 반대의 경우도 마찬가지입니다.

즉, C++ Interop는 가능한 가장 빠른 데이터 마샬링 방법을 사용하는 반면 P/Invoke는 가장 강력한 메서드를 사용합니다. 즉, C++ Interop(C++의 일반적인 방식으로)는 기본적으로 최적의 성능을 제공하며 프로그래머가 이 동작이 안전하지 않거나 적절하지 않은 경우를 처리합니다.

따라서 C++ Interop에서는 데이터 마샬링을 명시적으로 제공해야 하지만, 이점은 프로그래머가 데이터의 특성과 사용 방법을 고려할 때 적절한 것을 자유롭게 결정할 수 있다는 것입니다. 또한 P/Invoke 데이터 마샬링 동작을 어느 정도 사용자 지정하여 수정할 수 있지만 C++ Interop에서는 호출 기준으로 데이터 마샬링을 사용자 지정할 수 있습니다. P/Invoke에서는 이 작업을 수행할 수 없습니다.

C++ Interop에 대한 자세한 내용은 C++ Interop 사용(암시적 PInvoke)을 참조하세요.

참고 항목

혼합형(네이티브 및 관리) 어셈블리