Most definitely interesting. https://golang.org/src/cmd/compile/internal/ssa/rewriteAMD64.go#L54447 Am I correct to assume that DUFFCOPY is and optimization for MOVE?
If so, i wonder why the first example did not generate any MOV command at all. On Friday, April 24, 2020 at 4:25:51 PM UTC+2, Tamás Gulácsi wrote: > > 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/19743410-e4c6-4ca2-aee9-a0ba59afc4df%40googlegroups.com.