수색…


비고

인라인 확장은 바이너리 크기보다 성능을 우선시하는 컴파일 된 코드의 일반적인 최적화입니다. 컴파일러는 함수 호출을 함수의 실제 본문으로 대체 할 수 있습니다. 컴파일 타임에 효과적으로 한 곳에서 다른 곳으로 코드 복사 / 붙여 넣기. 호출 사이트는 컴파일러가 함수에 대해 생성 한 시스템 명령어를 포함하도록 확장 되었기 때문에 CALL 또는 PUSH (GOTO 문의 스택 또는 스택 프레임 푸시에 해당하는 x86) 또는 그와 동등한 것을 수행 할 필요가 없습니다 아키텍처.

인라이너는 여러 가지 추론을 기반으로 함수를 인라인할지 여부를 결정하지만 일반적으로 기본적으로 인라인으로 이동합니다. inliner는 함수 호출을 없애기 때문에 스케줄러가 goroutine을 선점 할 수있는 위치를 효과적으로 결정합니다.

함수 호출은 다음 중 하나라도 해당되면 인라인되지 않습니다 (다른 많은 이유도 있지만이 목록은 불완전합니다).

  • 함수는 가변적입니다 (예 : arg ... ).
  • 함수는 예산보다 큰 "최대 털이"를가집니다 (너무 많이 재발하거나 다른 이유로 분석 할 수 없음)
  • 그들은 panic , recover 또는 defer

인라인 확장 사용 중지

인라인 확장은 go:noinline pragma go:noinline 비활성화 할 수 있습니다. 예를 들어, 다음과 같은 간단한 프로그램을 빌드하면 :

package main
 
func printhello() {
    println("Hello")
}
 
func main() {
    printhello()
}

우리는 다음과 같은 출력을 얻습니다 (가독성을 위해 조정).

$ go version
go version go1.6.2 linux/amd64
$ go build main.go
$ ./main
Hello
$ go tool objdump main
TEXT main.main(SB) /home/sam/main.go
        main.go:7       0x401000        64488b0c25f8ffffff      FS MOVQ FS:0xfffffff8, CX
        main.go:7       0x401009        483b6110                CMPQ 0x10(CX), SP
        main.go:7       0x40100d        7631                    JBE 0x401040
        main.go:7       0x40100f        4883ec10                SUBQ $0x10, SP
        main.go:8       0x401013        e8281f0200              CALL runtime.printlock(SB)
        main.go:8       0x401018        488d1d01130700          LEAQ 0x71301(IP), BX
        main.go:8       0x40101f        48891c24                MOVQ BX, 0(SP)
        main.go:8       0x401023        48c744240805000000      MOVQ $0x5, 0x8(SP)
        main.go:8       0x40102c        e81f290200              CALL runtime.printstring(SB)
        main.go:8       0x401031        e89a210200              CALL runtime.printnl(SB)
        main.go:8       0x401036        e8851f0200              CALL runtime.printunlock(SB)
        main.go:9       0x40103b        4883c410                ADDQ $0x10, SP
        main.go:9       0x40103f        c3                      RET
        main.go:7       0x401040        e87b9f0400              CALL runtime.morestack_noctxt(SB)
        main.go:7       0x401045        ebb9                    JMP main.main(SB)
        main.go:7       0x401047        cc                      INT $0x3
        main.go:7       0x401048        cc                      INT $0x3
        main.go:7       0x401049        cc                      INT $0x3
        main.go:7       0x40104a        cc                      INT $0x3
        main.go:7       0x40104b        cc                      INT $0x3
        main.go:7       0x40104c        cc                      INT $0x3
        main.go:7       0x40104d        cc                      INT $0x3
        main.go:7       0x40104e        cc                      INT $0x3
        main.go:7       0x40104f        cc                      INT $0x3
…

printhello 대한 CALL 이 없음을 printhello . 그러나, 만약 우리가 프라그마 (pragma)를 사용하여 프로그램을 빌드한다면 :

package main
 
//go:noinline
func printhello() {
    println("Hello")
}
 
func main() {
    printhello()
}

출력에는 printhello 함수와 CALL main.printhello .

$ go version
go version go1.6.2 linux/amd64
$ go build main.go
$ ./main
Hello
$ go tool objdump main
TEXT main.printhello(SB) /home/sam/main.go
        main.go:4       0x401000        64488b0c25f8ffffff      FS MOVQ FS:0xfffffff8, CX
        main.go:4       0x401009        483b6110                CMPQ 0x10(CX), SP
        main.go:4       0x40100d        7631                    JBE 0x401040
        main.go:4       0x40100f        4883ec10                SUBQ $0x10, SP
        main.go:5       0x401013        e8481f0200              CALL runtime.printlock(SB)
        main.go:5       0x401018        488d1d01130700          LEAQ 0x71301(IP), BX
        main.go:5       0x40101f        48891c24                MOVQ BX, 0(SP)
        main.go:5       0x401023        48c744240805000000      MOVQ $0x5, 0x8(SP)
        main.go:5       0x40102c        e83f290200              CALL runtime.printstring(SB)
        main.go:5       0x401031        e8ba210200              CALL runtime.printnl(SB)
        main.go:5       0x401036        e8a51f0200              CALL runtime.printunlock(SB)
        main.go:6       0x40103b        4883c410                ADDQ $0x10, SP
        main.go:6       0x40103f        c3                      RET
        main.go:4       0x401040        e89b9f0400              CALL runtime.morestack_noctxt(SB)
        main.go:4       0x401045        ebb9                    JMP main.printhello(SB)
        main.go:4       0x401047        cc                      INT $0x3
        main.go:4       0x401048        cc                      INT $0x3
        main.go:4       0x401049        cc                      INT $0x3
        main.go:4       0x40104a        cc                      INT $0x3
        main.go:4       0x40104b        cc                      INT $0x3
        main.go:4       0x40104c        cc                      INT $0x3
        main.go:4       0x40104d        cc                      INT $0x3
        main.go:4       0x40104e        cc                      INT $0x3
        main.go:4       0x40104f        cc                      INT $0x3
 
TEXT main.main(SB) /home/sam/main.go
        main.go:8       0x401050        64488b0c25f8ffffff      FS MOVQ FS:0xfffffff8, CX
        main.go:8       0x401059        483b6110                CMPQ 0x10(CX), SP
        main.go:8       0x40105d        7606                    JBE 0x401065
        main.go:9       0x40105f        e89cffffff              CALL main.printhello(SB)
        main.go:10      0x401064        c3                      RET
        main.go:8       0x401065        e8769f0400              CALL runtime.morestack_noctxt(SB)
        main.go:8       0x40106a        ebe4                    JMP main.main(SB)
        main.go:8       0x40106c        cc                      INT $0x3
        main.go:8       0x40106d        cc                      INT $0x3
        main.go:8       0x40106e        cc                      INT $0x3
        main.go:8       0x40106f        cc                      INT $0x3
…


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow