Zig Version
0.16.0
Steps to Reproduce and Observed Behavior
$ git clone https://codeberg.org/kiesel-js/kiesel
$ zig build -Doptimize=ReleaseFast -Dtarget=x86_64-linux-musl -Denable-intl=false -Denable-temporal=false
$ objdump --no-addresses --no-show-raw-insn --disassemble='compiler_rt.memset' ./zig-out/bin/kiesel
./zig-out/bin/kiesel: file format elf64-x86-64
Disassembly of section .text:
<compiler_rt.memset>:
mov %rdi,%rax
test %rdx,%rdx
je <compiler_rt.memset+0x81>
mov %rdx,%r8
mov %rdx,%rdi
mov %rax,%rcx
and 0ドルx7,%r8
je <compiler_rt.memset+0x36>
xor %ecx,%ecx
nopl 0x0(%rax)
mov %sil,(%rax,%rcx,1)
add 0ドルx1,%rcx
cmp %rcx,%r8
jne <compiler_rt.memset+0x20>
mov %rdx,%rdi
sub %rcx,%rdi
add %rax,%rcx
cmp 0ドルx8,%rdx
jb <compiler_rt.memset+0x81>
push %rbp
mov %rsp,%rbp
xor %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl 0x0(%rax)
mov %sil,(%rcx,%rdx,1)
mov %sil,0x1(%rcx,%rdx,1)
mov %sil,0x2(%rcx,%rdx,1)
mov %sil,0x3(%rcx,%rdx,1)
mov %sil,0x4(%rcx,%rdx,1)
mov %sil,0x5(%rcx,%rdx,1)
mov %sil,0x6(%rcx,%rdx,1)
mov %sil,0x7(%rcx,%rdx,1)
add 0ドルx8,%rdx
cmp %rdx,%rdi
jne <compiler_rt.memset+0x50>
pop %rbp
ret
Compare to 0.15 which used musl's memset:
.global memset
.type memset,@function
memset:
movzbq %sil,%rax
mov 0ドルx101010101010101,%r8
imul %r8,%rax
cmp 126,ドル%rdx
ja 2f
test %edx,%edx
jz 1f
mov %sil,(%rdi)
mov %sil,-1(%rdi,%rdx)
cmp 2,ドル%edx
jbe 1f
mov %ax,1(%rdi)
mov %ax,(-1-2)(%rdi,%rdx)
cmp 6,ドル%edx
jbe 1f
mov %eax,(1+2)(%rdi)
mov %eax,(-1-2-4)(%rdi,%rdx)
cmp 14,ドル%edx
jbe 1f
mov %rax,(1+2+4)(%rdi)
mov %rax,(-1-2-4-8)(%rdi,%rdx)
cmp 30,ドル%edx
jbe 1f
mov %rax,(1+2+4+8)(%rdi)
mov %rax,(1+2+4+8+8)(%rdi)
mov %rax,(-1-2-4-8-16)(%rdi,%rdx)
mov %rax,(-1-2-4-8-8)(%rdi,%rdx)
cmp 62,ドル%edx
jbe 1f
mov %rax,(1+2+4+8+16)(%rdi)
mov %rax,(1+2+4+8+16+8)(%rdi)
mov %rax,(1+2+4+8+16+16)(%rdi)
mov %rax,(1+2+4+8+16+24)(%rdi)
mov %rax,(-1-2-4-8-16-32)(%rdi,%rdx)
mov %rax,(-1-2-4-8-16-24)(%rdi,%rdx)
mov %rax,(-1-2-4-8-16-16)(%rdi,%rdx)
mov %rax,(-1-2-4-8-16-8)(%rdi,%rdx)
1: mov %rdi,%rax
ret
2: test 15,ドル%edi
mov %rdi,%r8
mov %rax,-8(%rdi,%rdx)
mov %rdx,%rcx
jnz 2f
1: shr 3,ドル%rcx
rep
stosq
mov %r8,%rax
ret
2: xor %edx,%edx
sub %edi,%edx
and 15,ドル%edx
mov %rax,(%rdi)
mov %rax,8(%rdi)
sub %rdx,%rcx
add %rdx,%rdi
jmp 1b
Profiling shows compiler_rt memset is about 4x slower than musl:
Expected Behavior
Something as fundamental as memset should have decent performance before we drop the libc implementation.