[C++/CLI] 관리되는 함수에서 네이티브 함수를 호출할 때의 오버헤드

  • Post author:
  • Post category:
  • Post comments:0 Comments
  • Post last modified:July 19, 2007

2007.07.20 실험 조건을 조금 바꿔서 테스트를 다시 해봤다. 지난번엔 Debug 모드로 컴파일했는데, 이번에는 Release 모드에서 Use Link Time Code Generation 최적화 옵션을 추가했다. 뿐만 아니라 /clr 옵션을 제거한 완벽한 네이티브 C++과도 성능을 비교했다.

Best Practices for Writing Efficient and Reliable Code with C++/CLI를 보면 이런 대목이 있다.

One thing to keep in mind is that, even though C++ Interop will, in general, provide better performance when compared to P/Invoke, there is still a cost to the managed-to-native transition; therefore, keeping transitions to a minimum will help performance.

어느 정도의 오버헤드가 있는지 구체적으로 언급하지 않았기에 테스트해봤다. 결과는 주석으로 달아놨는데, 함수 호출 횟수를 생각하면 큰 문제라고 보긴 힘들지 않을까?라고 잠정적인 결론을 내려본다.

#pragma unmanaged
void NativeFunction()
{
	std::string s1 = " Test Test Test Test ";
	std::string s2 = " Performance Performance Performance Performance ";

	std::string merged(s1);
	merged.append(s2);
}

#pragma unmanaged
void NativeFunction2()
{
	for(int i=0; i<30000000; i++)
	{
		std::string s1 = " Test Test Test Test ";
		std::string s2 = " Performance Performance Performance Performance ";

		std::string merged(s1);
		merged.append(s2);
	}
}

#pragma managed
void ManagedFunction()
{
	DateTime prev = DateTime::Now;

	for(int i=0; i<30000000; i++)
	{
		NativeFunction();
	}

	TimeSpan passed = DateTime::Now - prev;
	Console::WriteLine(passed.ToString());
}

#pragma managed
void ManagedFunction2()
{
	DateTime prev = DateTime::Now;

	NativeFunction2();

	TimeSpan passed = DateTime::Now - prev;
	Console::WriteLine(passed.ToString());
}

int main(array<System::String ^> ^args)
{
	// 58.641 seconds
	ManagedFunction();

	// 58.071 seconds
	ManagedFunction2();

	return 0;
}

완전한 네이티브 C++로 ManagedFunction()과 비슷한 코드를 만들어 테스트해봤다. /clr 옵션을 줬을 때 컴파일러가 멍청한 짓거리를 하지 않는지 확인해보고 싶었다. 너무 간단한 코드라 신빙성이 부족하지만, 결과만 봐선 일단 C++/CLI의 네이티브 코드가 순수 네이티브 코드와 다르지 않을 거라 추측할 수 있다.

void NativeFunction()
{
	std::string s1 = " Test Test Test Test ";
	std::string s2 = " Performance Performance Performance Performance ";

	std::string merged(s1);
	merged.append(s2);
}

void ManagedFunctionStub()
{
	clock_t prev = ::clock();

	for(int i=0; i<30000000; i++)
	{
		NativeFunction();
	}

	clock_t now = clock();
	double time_in_milliseconds = now - prev;

	std::cout << time_in_milliseconds / 1000 << " seconds passed." << std::endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
	// 59.578 seconds passed.
	ManagedFunctionStub();
	return 0;
}
Author Details
Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.
0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments