第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 for-range 的行為會根據(jù)切片結(jié)構(gòu)的大小而有所不同?

為什么 for-range 的行為會根據(jù)切片結(jié)構(gòu)的大小而有所不同?

Go
湖上湖 2022-06-01 11:34:31
我在玩這個代碼main_var.gopackage mainfunc main() {    const size = 1000000    slice := make([]SomeStruct, size)    for _, s := range slice { // line 7        _ = s    }}type_small.gopackage maintype SomeStruct struct {    ID0 int64    ID1 int64    ID2 int64    ID3 int64    ID4 int64    ID5 int64    ID6 int64    ID7 int64    ID8 int64}我注意到,如果我在ID9結(jié)構(gòu)中添加另一個 64 位 int64(總共 10 * 8 字節(jié) = 80 字節(jié)),則 for 循環(huán)會變慢。如果我比較了程序集,它添加了復(fù)制元素的指令// with 9 int64 (72 bytes)    0x001d 00029 (main_var.go:6)    LEAQ    type."".SomeStruct(SB), AX    0x0024 00036 (main_var.go:6)    MOVQ    AX, (SP)    0x0028 00040 (main_var.go:6)    MOVQ    $1000000, 8(SP)    0x0031 00049 (main_var.go:6)    MOVQ    $1000000, 16(SP)    0x003a 00058 (main_var.go:6)    CALL    runtime.makeslice(SB)    0x003f 00063 (main_var.go:6)    XORL    AX, AX    0x0041 00065 (main_var.go:7)    INCQ    AX    0x0044 00068 (main_var.go:7)    CMPQ    AX, $1000000    0x004a 00074 (main_var.go:7)    JLT    65    0x004c 00076 (main_var.go:7)    MOVQ    32(SP), BP    0x0051 00081 (main_var.go:7)    ADDQ    $40, SP    0x0055 00085 (main_var.go:7)    RET    0x0056 00086 (main_var.go:7)    NOP    0x0056 00086 (main_var.go:3)    CALL    runtime.morestack_noctxt(SB)    0x005b 00091 (main_var.go:3)    JMP    0// with 10 int64 (80 bytes), it added DUFFCOPY instruction    0x001d 00029 (main_var.go:6)    LEAQ    type."".SomeStruct(SB), AX    0x0024 00036 (main_var.go:6)    MOVQ    AX, (SP)    0x0028 00040 (main_var.go:6)    MOVQ    $1000000, 8(SP)    0x0031 00049 (main_var.go:6)    MOVQ    $1000000, 16(SP)    0x003a 00058 (main_var.go:6)    CALL    runtime.makeslice(SB)    0x003f 00063 (main_var.go:6)    MOVQ    24(SP), AX    0x0044 00068 (main_var.go:6)    XORL    CX, CX    0x0046 00070 (main_var.go:7)    JMP    76我想知道為什么較大的結(jié)構(gòu)(> 80 字節(jié))的不同行為即使在這兩種情況下都沒有使用切片的元素。
查看完整描述

1 回答

?
慕雪6442864

TA貢獻(xiàn)1812條經(jīng)驗 獲得超5個贊

我發(fā)現(xiàn)這是因為 SSA 優(yōu)化。lower在傳遞過程中更明確。此過程將中間表示更改為特定于機(jī)器的裝配。


在writebarrier(前 1 步lower)處,兩種結(jié)構(gòu)尺寸的說明仍然相同。


        v22 (7) = Phi <*SomeStruct> v14 v45

        v28 (7) = Phi <int> v16 v37

        v23 (7) = Phi <mem> v12 v27

        v37 (+7) = Add64 <int> v28 v36

        v39 (7) = Less64 <bool> v37 v8

        v25 (7) = VarDef <mem> {.autotmp_7} v23

        v26 (7) = LocalAddr <*SomeStruct> {.autotmp_7} v2 v25

        v27 (+7) = Move <mem> {SomeStruct} [72] v26 v22 v25  # <-- copy operation


如您所見, Move在 v27 上有操作。


然而,在lower通過之后,指令就不同了。


有 9 個 int64(72 字節(jié))


        v22 (7) = Phi <*SomeStruct> v14 v45

        v28 (7) = Phi <int> v16 v37

        v23 (7) = Phi <mem> v12 v27

        v37 (+7) = ADDQconst <int> [1] v28

        v25 (7) = VarDef <mem> {.autotmp_7} v23

        v26 (7) = LEAQ <*SomeStruct> {.autotmp_7} v2

        v44 (7) = CMPQconst <flags> [1000000] v37

        v32 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [8] v2

        v31 (+7) = ADDQconst <*SomeStruct> [8] v22

        v29 (+7) = MOVQload <uint64> v22 v25

        v24 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [40] v2

        v15 (+7) = ADDQconst <*SomeStruct> [40] v22

        v46 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [56] v2

        v35 (+7) = ADDQconst <*SomeStruct> [56] v22

        v21 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [24] v2

        v17 (+7) = ADDQconst <*SomeStruct> [24] v22

        v39 (7) = SETL <bool> v44

        v42 (7) = TESTB <flags> v39 v39

        v30 (+7) = MOVQstore <mem> {.autotmp_7} v2 v29 v25

        v41 (+7) = MOVOload <int128> [8] v22 v30

        v20 (+7) = MOVOstore <mem> {.autotmp_7} [8] v2 v41 v30

        v34 (+7) = MOVOload <int128> [24] v22 v20

        v19 (+7) = MOVOstore <mem> {.autotmp_7} [24] v2 v34 v20

        v33 (+7) = MOVOload <int128> [40] v22 v19

        v38 (+7) = MOVOstore <mem> {.autotmp_7} [40] v2 v33 v19

        v47 (+7) = MOVOload <int128> [56] v22 v38

        v27 (+7) = MOVOstore <mem> {.autotmp_7} [56] v2 v47 v38


具有 10 個 int64(80 字節(jié)),它使用 DUFFCOPY 設(shè)備優(yōu)化 MOVE


    v22 (7) = Phi <*SomeStruct> v14 v45

    v28 (7) = Phi <int> v16 v37

    v23 (7) = Phi <mem> v12 v27

    v37 (+7) = ADDQconst <int> [1] v28

    v25 (7) = VarDef <mem> {.autotmp_7} v23

    v26 (7) = LEAQ <*SomeStruct> {.autotmp_7} v2

    v44 (7) = CMPQconst <flags> [1000000] v37

    v32 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [8] v2

    v31 (+7) = ADDQconst <*SomeStruct> [8] v22

    v29 (+7) = MOVQload <uint64> v22 v25

    v39 (7) = SETL <bool> v44

    v42 (7) = TESTB <flags> v39 v39

    v30 (+7) = MOVQstore <mem> {.autotmp_7} v2 v29 v25

    v27 (+7) = DUFFCOPY <mem> [826] v32 v31 v30 # <---

這種優(yōu)化是由于rewriteAMD64.go 上的這條規(guī)則


match: (Move [s] dst src mem)

cond: s > 64 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice

result: (DUFFCOPY [14*(64-s/16)] dst src mem)

在后期(elim unread autos),SSA 優(yōu)化可以檢測到臨時變量autotmp_7沒有被使用并且可以被移除。使用 DUFFCOPY 的較大結(jié)構(gòu)不是這種情況


我在這里寫得更詳細(xì)一點


查看完整回答
反對 回復(fù) 2022-06-01
  • 1 回答
  • 0 關(guān)注
  • 146 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號