美文网首页
当系统调用变为瓶颈

当系统调用变为瓶颈

作者: 谭英智 | 来源:发表于2024-05-14 22:30 被阅读0次

    当程序在操作文件,网络传输时,都会发生系统调用

    系统调用会让线程切换用户态和内核态,并且当系统调用长时间没返回,会导致线程阻塞,并无法处理其他事情

    system call latency

    下图是getpid在发生系统调用时和不使用系统调用时的latency对比。

    syscall.PNG

    可以看到带system call 的 getpid latency是200ns

    不带system call 的 getpid latency是8.7ns

    相差20倍

    write system call latency

    通过下面的benchmark数据可以看到

    latency在3us左右

    writev_t1k reported mean: 6.17776
     500: mean 6.018us median 6us
    1000: mean 5.172us median 5us
    1500: mean 5.048us median 5us
    2000: mean 3.918us median 4us
    
    writev_t1k reported mean: 5.64197
     500: mean 6.254us median 6us
    1000: mean 5.038us median 6us
    1500: mean 3.526us median 4us
    2000: mean 3.608us median 4us
    
    writev_t1k reported mean: 4.33704
     500: mean 3.528us median 3us
    1000: mean 3.486us median 3us
    1500: mean 3.518us median 3us
    2000: mean 3.492us median 3us
    

    换句话说,当程序在调用系统调用write时,程序会停顿3us,并无法处理其实事情

    一个可能的解决方案 io_uring?

    io_uring是内核5.9以上才会有

    一般来说,目前广泛使用的linux版本一般比这低

    而且 io_uring在处理stream mode时,性能不如epoll

    为了解决这些问题,提出以下解决方案:

    • 编写自定义内核模块

      • 在内核建立epoll对fd的监控

      • 在内核启动线程,做fd polling和polling来自用户态的数据

      • 建立一片共享内存,与用户态公用,并在共享内存上,建立单读单写无锁队列

      • 对fd的读写消息,通过共享内存返回ack给用户态

    • 用户态程序

      • 获取共享内存,并处理共享内存上队列的请求

      • 单线程polling无锁队列,实现与内核线程的交互

      • 获取共享内存中的ack,来做限流操作

    相关文章

      网友评论

          本文标题:当系统调用变为瓶颈

          本文链接:https://www.haomeiwen.com/subject/mocvfjtx.html