2009-03-05 2 views
23

픽셀 별 충돌 검사를 수행하는 XNA 게임을 작성하고 있습니다. 이것을 검사하는 루프는 int와 bitwise ORing을 이동하여 수행하며 일반적으로 읽고 이해하기 어렵습니다.C# 컴파일러가 메서드 호출을 인라인했는지 확인할 수 있습니까?

private bool IsTransparent(int pixelColorValue)과 같은 개인 메서드를 추가하여 루프를보다 읽기 쉽게하고 싶습니다. 그러나이 메서드는 성능에 민감한 코드이므로 메서드 호출의 오버 헤드를 원하지 않습니다.

컴파일러에서이 호출을 강제 실행하는 방법이 있습니까, 아니면 컴파일러에서이 최적화를 수행하기를 바랍니다.

강제하는 방법이 없으면 메소드가 인라인되었는지, 디스 어셈블리를 읽지 않는지 확인하는 방법이 있습니까? 인라인되어 있고 다른 호출자가없는 경우 메서드가 리플렉션에 표시됩니까?

편집 : 강제로 설정할 수 없으므로 검색 할 수 있습니까?

+1

(.Net 4.5). '[MethodImpl (MethodImplOptions.AggressiveInlining)] ' – Mahmoodvcs

답변

23

아니 당신은 할 수 없습니다. 더욱이, 인라이닝을 결정하는 사람은 코드를 가져와 IL로 변환하는 VS 컴파일러가 아니라 IL을 사용하여이를 기계 코드로 변환하는 JIT 컴파일러입니다. 이것은 JIT 컴파일러만이 인스트럭션 파이프 라이닝과 캐시 ​​크기 사이의 균형이 맞으므로 인라인 방식을 사용하는 것이 적절한 지 결정하기 위해 프로세서 아키텍처에 대해 충분히 알고 있기 때문입니다.

그래서 .NET Reflector를 보면 도움이되지 않습니다.

+0

다른 사람들은 호출 스택을 사용하기 때문에 리플렉션에 대해 다른 것을 구걸합니다. http://stackoverflow.com/questions/44153/can-you-use-reflection-to-find-the-name-of-the-currently-executing-method/44171#44171 –

+1

나는 반사를 말하지 않았다. 리플렉터는 Red Gates .NET Reflector 에서처럼 –

+0

내 잘못, 나는 그것을 오해했다. –

1

아니요.

기본적으로 대부분의 최신 C++ 컴파일러에서 그렇게 할 수 없습니다. inline은 컴파일러에게만 제공됩니다. 가져갈 수 있는지 여부는 자유 롭습니다.

C# 컴파일러는 IL 수준에서 특수 인라인을 수행하지 않습니다. JIT 최적화 프로그램이이를 수행 할 것입니다.

+0

"강제하는 방법이 없다면, 메소드가 인라인되었는지, 디스 어셈블리를 읽지 못하는지, 메소드가 리플렉션에 나타나는지 확인하는 방법이 있습니까? 그것이 인라인되었고 다른 발신자가 없다면? " –

+0

아니, C# 컴파일러가 인라이닝을 전혀하지 않는다고 생각합니다. JIT 컴파일러가 이에 대한 책임이 있습니다. –

+0

System.Reflection.MethodBase.GetCurrentMethod(). Name을 확인할 수 있습니다. 메소드가 인라인되면, 대신 호출자의 이름이 리턴됩니다. –

14

"확인할 수 있습니다 System.Reflection.MethodBase.GetCurrentMethod(). 메소드가 인라인되면 이름입니다. , 그것은 대신 발신자 의 이름을 반환합니다."

-Joel Coehoorn

+0

런타임에만 작동합니다. –

+19

물론 런타임시에만 작동합니다. 인라인이 발생할 때입니다. –

+10

코드에서이 메서드를 호출하면 실제 IL이 변경되지 않고 JIT 컴파일러의 '추론'이 인라인되어야하는지 여부가 이론적으로 변경됩니다. –

0

위에서 설명한 GetCurrentMethod 호출을 사용하여 런타임에이를 감지 할 수 있습니다. 그러나 그것은 약간의 낭비처럼 보입니다. 가장 쉬운 방법은 MSIL을 ILDASM하고 거기서 확인하는 것입니다.

컴파일러은 전화를 인라이닝하고 MSDN의 다양한 Reflection 문서에서 다룹니다.

GetCallingAssembly 해당 메소드를 호출하는 방법 (컴파일러 (방출은 Microsoft 중간 언어로 MSIL를 기능 체를 삽입하는 경우 즉,) 대신 함수 호출 발광 이상)이면 컴파일러에 의해 인라인으로 확장되면 GetCallingAssembly 메서드에서 반환 된 어셈블리는 인라인 코드가 들어있는 어셈블리입니다. 이는 원래 방법이 포함 된 어셈블리와 다를 수 있습니다. GetCallingAssembly 메서드를 호출하는 메서드가 컴파일러에 의해 인라인되지 않도록하려면 MethodImplOptions.NoInlining과 함께 MethodImplAttribute 특성을 적용하면됩니다.

그러나 JITter는 무료로 인라인 통화를 할 수 있습니다.하지만 디스 어셈블러가 해당 레벨에서 수행되는 작업과 수행되지 않은 작업을 확인할 수있는 유일한 방법 일 것입니다.

편집 :이 스레드에서 약간의 혼동을 정리하기 위해, csc.exe will inline MSIL calls - JITter가 (아마도) 공격적 일 것입니다.

[1] 그리고 낭비로, (a) 리플렉션 조회 때문에 인라이닝 (더 나은 성능)의 목적을 상실한다는 것을 의미합니다. 그리고 (b), 인라인 동작이 변경되어 아마 더 이상 인라인되지 않습니다. 그리고 디버그에서 Assert 또는 무언가를 사용하여 디버그를 빌드 할 수 있다고 생각하기 전에 디버그 중에는 인라인되지 않지만 Release에있을 수 있습니다.

+0

예 : 런타임에 이것을 테스트하는 것은 낭비입니다. JIT'd 인라인이라면 아마도 그럴만한 이유가 있었을 것입니다. 그러나 나는 이것을 더 많은 학습 훈련으로 생각했습니다 : 그는 자신을 위해 인라인을 경험하고 싶습니다. –

1

안전하지 않은 코드 (알려진대로 인라인 c)를 사용하고 c/C++ 스타일 포인터를 사용하지 않는 이유는 GC (즉, 콜렉션의 영향을받지 않음)로부터 안전하지만 자체 보안 의미 인터넷 영역 애플 리케이션)하지만 그것은 특히 당신이 성능과 특히 배열 및 비트 연산과 함께 달성하고자하는 일종의 우수합니다?

요약하면 앱의 작은 부분에 대한 성능을 원하십니까? 안전하지 않은 코드를 사용하고 포인터 등을 사용하는 것이 나에게 가장 좋은 옵션 인 것 같습니다.

EDIT : 약간의 시동기? http://msdn.microsoft.com/en-us/library/aa288474(VS.71).aspx

+4

안전하지 않은 코드는 관리 코드보다 느린 경우가 많습니다. JIT가 코드에 대해 많은 보장을 할 수 없기 때문에 특정 최적화를 수행 할 수 없기 때문입니다. 그래서 당신이 이것을한다면, 언제나처럼, ** profile! ** –

0

이 호출을 인라인 컴파일러를 강제 할 수있는 방법이 있나요 아니면 그냥 컴파일러는이 최적화를 할 수 있기를 바랍니다 할 것인가?

기능을 인라인하면 저렴합니다. 프로파일 러가 실제로 문제라고 말하지 않으면 걱정하지 마십시오.

JIT Enhancements in .NET 3.5 SP1

4

자세한 내용은

은 X 박스가 다른 작동하는지 알고 있어야합니다. 방법의 호출의 오버 헤드를 완화

"인라인 방식 JIT 형태를 다음과 같은 조건을 충족 어떤 인라인으로

  • 일리노이 번호 :

    구글이 걷어.. 크기가 16 바이트 이하인.

  • 분기 명령을 사용하지 않는 (있다면 문장 등). 로컬 변수를 사용하지
  • .
  • 인 0
  • 예외 처리가 수행되지 않았습니다 (시도, 캐치 등) .
  • float가 인수로 사용되지 않았거나 메서드의 반환 값 (아마도 에 의해 적용되지 않았습니다.).
  • 두 개 이상의 인수가 메서드에있는 경우 선언을 위해 사용합니다.

그러나 가상 함수는 인라인으로 형성되지 않습니다.그가 맞다면 "

http://xnafever.blogspot.com/2008/07/inline-method-by-xna-on-xbox360.html

는 나도 몰라. 누구?

+0

이것을 지적 해 주셔서 감사합니다. 그것은 실제로 나에게 상당히 관련이 있습니다. 그래도 공식 문서에서 그것을 보는 것은 좋을 것이다. –

1

이 가져 오거나 프로파일을 작성하고, JIT 이벤트에 후크하는 것입니다 확인하는 유일한 방법, 당신은 또한 확인해야 프로파일 링 할 때 기본적으로 그대로 확인 인라인이 해제되지

14

여기에 설명되어 .NET 4.5에서 더 공격적 인라인을 장려하는 새로운 방법이있다 :. http://blogs.microsoft.co.il/blogs/sasha/archive/2012/01/20/aggressive-inlining-in-the-clr-4-5-jit.aspx

은 기본적으로는 테 단지 플래그이다가 가능한 경우 컴파일러에서 인라인 할 것입니다. 유감스럽게도 현재 버전의 XNA (Game Studio 4.0)에서는 사용할 수 없지만 XNA가 올해에 VS 2012를 따라 잡을 때 사용할 수 있어야합니다. Mono를 어떻게 든 사용하고 있다면 이미 사용할 수 있습니다.

[MethodImpl(MethodImplOptions.AggressiveInlining)] 
public static int LargeMethod(int i, int j) 
{ 
    if (i + 14 > j) 
    { 
     return i + j; 
    } 
    else if (j * 12 < i) 
    { 
     return 42 + i - j * 7; 
    } 
    else 
    { 
     return i % 14 - j; 
    } 
} 
관련 문제