2020. április 24., péntek 14:26:08 UTC+2 időpontban Yulrizka a következőt írta: > > Hello, > > > I was playing around with this code > > main_var.go > package main > > func main() { > const size = 1000000 > > slice := make([]SomeStruct, size) > for _, s := range slice { // line 7 > _ = s > } > > } > > > type_small.go > package main > > type SomeStruct struct { > ID0 int64 > ID1 int64 > ID2 int64 > ID3 int64 > ID4 int64 > ID5 int64 > ID6 int64 > ID7 int64 > ID8 int64 > } > > > I noted that if i added anoteher 64 bit int64 `ID9` (total of 10 * 8 byte > = 80 byte) integer to the struct, the for-loop becomes slower. > And if I compare the assembly, it added instruction to copy the element > > // 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 > 0x0048 00072 (main_var.go:7) ADDQ $80, AX > 0x004c 00076 (main_var.go:7) LEAQ ""..autotmp_7+32(SP), DI > 0x0051 00081 (main_var.go:7) MOVQ AX, SI > 0x0054 00084 (main_var.go:7) DUFFCOPY $826 # <-- copy the > element > 0x0067 00103 (main_var.go:7) INCQ CX > 0x006a 00106 (main_var.go:7) CMPQ CX, $1000000 > 0x0071 00113 (main_var.go:7) JLT 72 > 0x0073 00115 (main_var.go:7) MOVQ 112(SP), BP > 0x0078 00120 (main_var.go:7) ADDQ $120, SP > 0x007c 00124 (main_var.go:7) RET > 0x007d 00125 (main_var.go:7) NOP > 0x007d 00125 (main_var.go:3) CALL runtime.morestack_noctxt(SB) > 0x0082 00130 (main_var.go:3) JMP 0 > > > I am just curious to why the bahavior is different on larger struct (> 80 > bytes) even though in both cases the element of the slice is not being use. > > Thank you >
After grepping the sources for DUFFCOPY, ./cmd/compile/internal/ssa/rewriteAMD64.go suggests that it is a DUFFCOPY before SSA rewrites it to something faster - and this is a size-depending operation. But I may be totally wrong... -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/a5d6949c-2dbe-498e-b7b5-e12eb14ccf08%40googlegroups.com.