You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Linux下libc的putchar比直接系统调用write更快?

直接调用syscall比putchar慢2.5倍的反常现象

我正在针对Linux平台做代码深度优化,搭建了一个基于rdtsc的时钟周期计时框架,原本想通过直接调用Linux系统调用来替代libc函数提升性能(注:每次最多输出一个无格式字符)。但测试结果却显示putchar的速度比直接调用syscall快两倍多(时钟周期通过rdtsc获取,以64位十六进制整数展示,差值较小时补充十进制数值)。

注意:测试无重复,仅执行一次以下代码进行计时。

syscall测试代码及结果

汇编代码:

# %rdi contains a string
    movq $1 , %rax # system call 1: write
    movq %rdi, %rsi # what: char pointer
    movq $1 , %rdi # where: stdout
    movq $1 , %rdx # how many bytes: 1
    syscall

计时结果:

__________________________________
RDTSC   后值:   0x0002c22fbac1c7b5
RDTSC   前值:   0x0002c22fbabf4d1f
时钟周期:   0x0000000000027a96
时钟周期:   162454

putchar测试代码及结果

汇编代码:

# %rdi contains a string
    mov %rdi, %rsi
    xor %edi, %edi
    movb (%rsi), %dil
    call putchar

计时结果:

__________________________________
RDTSC   后值:   0x0002c221713726cd
RDTSC   前值:   0x0002c2217136469f
时钟周期:   0x000000000000e02e
时钟周期:   57390

注意:尽管仅展示一组结果,但多次测试均显示syscall方法的速度约慢2.5倍。

疑惑:putchar的内部执行流程反而更复杂

根据GDB单步调试得到的putchar内部执行流程来看,这个结果尤为反常,流程如下:

IO_validate_vtable (vtable=0x7ffff7e16600 <_IO_file_jumps>) at ./libio/libioP.h:943
943     ./libio/libioP.h: No such file or directory.
(gdb) 
__GI__IO_file_doallocate (fp=0x7ffff7e1a780 <_IO_2_1_stdout_>) at ./libio/libioP.h:947
947     in ./libio/libioP.h
(gdb) 
__GI__IO_file_stat (fp=0x7ffff7e1a780 <_IO_2_1_stdout_>, st=0x7fffffffde90) at ./libio/fileops.c:1146
1146    ./libio/fileops.c: No such file or directory.
(gdb) 
1147    in ./libio/fileops.c
(gdb) 
__GI___fstat64 (fd=1, buf=0x7fffffffde90) at ../sysdeps/unix/sysv/linux/fstat64.c:29
29      ../sysdeps/unix/sysv/linux/fstat64.c: No such file or directory.
(gdb) 
30      in ../sysdeps/unix/sysv/linux/fstat64.c
(gdb) 
35      in ../sysdeps/unix/sysv/linux/fstat64.c
(gdb) 
__GI___fstatat64 (fd=1, file=0x7ffff7dd846f "", buf=0x7fffffffde90, flag=4096) at ../sysdeps/unix/sysv/linux/fstatat64.c:153
153     ../sysdeps/unix/sysv/linux/fstatat64.c: No such file or directory.
(gdb) 
163     in ../sysdeps/unix/sysv/linux/fstatat64.c
(gdb) 
fstatat64_time64_stat (flag=4096, buf=0x7fffffffde90, file=0x7ffff7dd846f "", fd=1) at ../sysdeps/unix/sysv/linux/fstatat64.c:98
98      in ../sysdeps/unix/sysv/linux/fstatat64.c
(gdb) 
__GI___fstatat64 (fd=1, file=0x7ffff7dd846f "", buf=0x7fffffffde90, flag=4096) at ../sysdeps/unix/sysv/linux/fstatat64.c:166
166     in ../sysdeps/unix/sysv/linux/fstatat64.c
(gdb) 
__GI__IO_file_doallocate (fp=0x7ffff7e1a780 <_IO_2_1_stdout_>) at ./libio/filedoalloc.c:86
86      ./libio/filedoalloc.c: No such file or directory.
(gdb) 
91      in ./libio/filedoalloc.c
(gdb) 
__gnu_dev_major (__dev=34817) at ../include/sys/sysmacros.h:47
47      ../include/sys/sysmacros.h: No such file or directory.
(gdb) 
91      ./libio/filedoalloc.c: No such file or directory.
(gdb) 
94      in ./libio/filedoalloc.c
(gdb) 
97      in ./libio/filedoalloc.c
(gdb) 
101     in ./libio/filedoalloc.c
(gdb) 
__GI___libc_malloc (bytes=bytes@entry=1024) at ./malloc/malloc.c:3287
3287    ./malloc/malloc.c: No such file or directory.
(gdb) 
3294    in ./malloc/malloc.c
(gdb) 
3295    in ./malloc/malloc.c
(gdb) 
ptmalloc_init () at ./malloc/arena.c:315
315     ./malloc/arena.c: No such file or directory.
(gdb) 
ptmalloc_init () at ./malloc/arena.c:313
313     in ./malloc/arena.c
(gdb) 
321     in ./malloc/arena.c
(gdb) 
0x00007ffff7ca1a31 in tcache_key_initialize () at ./malloc/malloc.c:3162
3162    ./malloc/malloc.c: No such file or directory.
(gdb) 
318     ./malloc/arena.c: No such file or directory.
(gdb) 
321     in ./malloc/arena.c
(gdb) 
tcache_key_initialize () at ./malloc/malloc.c:3162
3162    ./malloc/malloc.c: No such file or directory.
(gdb) 
__GI___getrandom (buffer=buffer@entry=0x7ffff7e204d8 <tcache_key>, length=length@entry=8, flags=flags@entry=1) at ../sysdeps/unix/sysv/linux/getrandom.c:28

内容的提问来源于stack exchange,提问作者CasseroleBoi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 07:27:01