다음을 통해 공유


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

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

Visual C++는 Visual Basic이나 C# 같은 다른 .NET 언어와 동일한 상호 운용성 메커니즘(P/Invoke)을 지원할 뿐만 아니라 Visual C++에만 적용되는 interop 지원(C++ interop)도 제공합니다. 성능을 크게 고려해야 하는 응용 프로그램에서는 각 interop 기술이 성능에 미칠 수 있는 영향을 이해하는 것이 중요합니다.

어떠한 interop 기술을 사용하건 상관없이 관리되는 함수가 관리되지 않는 함수를 호출하거나 그 반대로 호출할 때마다 썽크라는 특별한 전환 시퀀스가 필요합니다. 이러한 썽크는 Visual C++ 컴파일러에서 자동으로 삽입되지만 이와 같은 전환은 누적되므로 성능이 저하될 수도 있다는 점을 염두에 둘 필요가 있습니다.

전환 줄이기

interop 썽크에 따른 성능 저하를 막거나 줄이기 위한 방법 중 하나로 관리/비관리 전환을 최소화하는 데 관련된 인터페이스를 리팩터링할 수 있습니다. 관리/비관리 경계를 넘나드는 잦은 호출과 관련하여 자주 사용되는 인터페이스를 대상으로 리팩터링하면 성능을 크게 향상시킬 수 있습니다. 예를 들어, 자주 반복되는 루프에서 관리되지 않는 함수를 호출하는 관리되는 함수를 리팩터링하면 큰 효과를 볼 수 있습니다. 루프 자체를 관리되지 않는 영역으로 옮기거나 (관리되는 영역에 데이터 큐를 대기시킨 다음 루프 이후에 이를 모두 한 번에 관리되지 않는 API로 마샬링하여) 관리되지 않는 호출에 상응하는 관리되는 호출을 만들어 전환 수를 크게 줄일 수도 있습니다.

P/Invoke vs. 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에서 네이티브 형식으로 마샬링됩니다.

  • 관리되는 함수에서 관리되지 않는 함수로의 썽크가 실행됩니다.

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

  • 관리되지 않는 함수에서 관리되는 함수로의 썽크가 실행됩니다.

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

관리/비관리 썽크는 interop 작동에 반드시 필요하지만, 어떠한 데이터 마샬링이 필요한지는 관련된 데이터 형식, 함수 시그니처, 데이터를 사용하는 방식에 따라 달라집니다.

C++ Interop에서 수행하는 데이터 마샬링은 가장 간단한 형태입니다. 비트 방식으로 관리/비관리 경계 너머로 매개 변수를 복사하기만 하고 변환은 전혀 수행하지 않습니다. P/Invoke의 경우 이러한 방식은 모든 매개 변수가 단순한 blittable 형식인 경우에만 적용됩니다. 그렇지 않으면 P/Invoke는 인수가 "out" 또는 "in,out"으로 표시되어 있는 경우 관리되는 각 매개 변수를 해당 네이티브 형식으로 변환하거나 그 반대로 변환하기 위한 매우 강력한 단계를 수행합니다.

즉, C++ Interop에서는 가능한 한 속도가 빠른 데이터 마샬링 방법을 사용하는 반면 P/Invoke에서는 가능한 한 강력한 방법을 사용합니다. 따라서 C++에 일반적으로 사용되는 방식인 C++ Interop는 기본적으로 최적화된 성능을 제공하며, 이 동작이 안전하지 않거나 적합하지 않은 경우에 발생하는 문제는 프로그래머가 직접 처리해야 합니다.

C++ Interop의 경우 데이터 마샬링을 명시적으로 제공해야 하지만 데이터의 성격과 데이터가 사용되는 방식을 지정하면 더 적합한 기술을 프로그래머가 직접 결정하지 않아도 된다는 이점이 있습니다. 또한 P/Invoke 데이터 마샬링 동작도 어느 정도까지는 사용자 지정하여 수정할 수 있지만 C++ Interop의 경우에는 데이터 마샬링을 각 호출별로 사용자 지정할 수 있습니다. P/Invoke에서는 이러한 융통성을 발휘할 수 없습니다.

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

참고 항목

개념

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