native C++코드와 .NET JIT 코드의 속도차이는 많이 좁혀진 상태지만,
요즘 컴퓨터에서는 SSE, SSE2, SSE3같은 SIMD(Single Instruction Multiple Data)라는 CPU 퍼포먼스를 향상시킬 수 있는 방법이 있으며 C++ 코드에서는 이를 사용하기 어렵지 않습니다.
(MSDN에서 Intrinsic 검색 'ㅁ'/)
그러나 .NET 환경에서 이에 관련된 루틴을 호출하려면 P/Invoke 또는 Deligate로 호출해야 합니다.
(오픈소스 C# 플랫폼인 mono에서는 Simd 패키지에서 지원해줍니다만.. )
이러한 호출은 managed 환경 <-> unmanaged 환경간의 컨텍스트 스위칭이 발생하므로 오버헤드가 추가됩니다.
분명히 속도향상은 있지만, 오버헤드로 인한 속도 저하는 계속 존재하므로, 이에 대한 대안으로 JIT 어셈블리에서 해당연산이 필요한 부분의 어셈블리 코드를 최적화된 SIMD 코드로 교체하는 트릭이 있습니다.
실제 구현은 CLR 프로파일러같은 일종의 디버깅툴로 해당연산에 대한 코드의 주소를 찾아내고 코드를 덮어씌워서 실시간으로 일반 루틴처럼 호출하는 것입니다.
참고 링크
C++로 SIMD를 사용하는 간단한 예제
http://www.windows-tech.info/17/88e26fcb3ca23cff.php
SFMT라는 수학관련 라이브러리에서 사용하는 예제
http://www.codeproject.com/KB/DLL/SFMT_dll.aspx
C++ wrapper로 C++/CLI에서 SIMD를 사용하는 예제
http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/50cd191d-583a-4bda-b9c0-1c05c2fd05bf
어셈블리 교체의 자세한 개념 설명
http://scapecode.com/category/net/
SlimGen
http://code.google.com/p/slimgen/
0 개의 댓글:
댓글 쓰기