저는 지난 며칠 동안 CIL을 배우는 데 여유 시간을 보냈고 레이블 (br)과 메소드 (.method 선언)를 호출하는 것에 대한 분기에 대해 궁금합니다.코드를 CIL의 레이블 또는 함수로 호출합니까?
메서드를 선언하면 어셈블리 외부에서 액세스 할 수 있지만 개인 메서드 레이블을 만들고 br
을 사용하여 분기하는 방법은 무엇인지 알고 있습니다. 거기에 성능 향상이 있습니까?
이 혼란을 정리하기 위해 여기에 (때문에 공간과 시간 제한) 단순화 된 예입니다
// calling code
ldc.i4 5
call int32 testmethod(int32)
// other code
// method
.method public int32 testmethod(int32)
{
ldc.i4 10
add
ldc.i4 20
mul
ret
}
그래서 대신 그 방법을하고, 내가 할 수있는 라벨과 지사를 가지고 :
ldc.i4 5
br testlabel
leftoff:
// remaining instructions
testlabel:
.lcd.i4 10
add
ldc.i4 20
mul
br leftoff
그래서 메소드/레이블 testlabel은 int32를 취한 다음 10을 더하고 그 결과에 20을 곱합니다. 단점 (원래는 언급하지 않았 음)은 가독성이지만 컴파일러가 생성하면 가독성이 덜 중요하다는 사실을 알고 있습니다. 따라서 두 번째 예제를 사용하면 레이블을 사용하고 코드를 분기하여 성능 이점을 얻을 수 있습니까? 그렇지 않다면 짧은 지류에 맞출 수 있을까요? (br.s)
재미있는 점은 메소드 인라이닝에 대한 이해가 전화 (또는 분기)를 작성하는 대신 코드가 기본적으로 호출이 이루어질 위치에 붙여 넣기된다는 점입니다. 당신은 여전히 점프/가지의 오버 헤드를 가지고 있기 때문에 레이블은 어떻게할까요? 아니면 메소드 인라이닝에 대한 정의를 기반으로하지 않습니까? – Jetti
@ 제티 - 글쎄, 나는 당신의 질문에서 외삽했다. 전화를 걸려는 사적인 방법으로 도약한다면, 일단 끝나면 어디로 돌아갈 지 어떻게 알 수 있습니까? 당신은 기본적으로이 메소드로 건너 뛰고 아마도 호출자에게로 돌아가고 싶습니다. 실제로 호출자에게로 건너 뛰기를 원할 것입니다. 이것은 실제로 라인에 있지 않다는 것을 제외하면 메소드를 인라이닝하는 것과 같습니다. – kvb
그러나 여러 호출 사이트가있는 경우 여분의 상태를 추적하여 어디로 돌아갈 지 결정해야합니다 (또는 메소드를 여러 번 인라인해야 함). – kvb