加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Windows上的系统调用本身是否比Linux慢?

发布时间:2020-12-14 01:48:40 所属栏目:Windows 来源:网络整理
导读:我对系统调用的理解是,在 Linux中,系统调用机制(int 0x80或其他)被记录在案,并保证在不同的内核版本中保持稳定.使用此信息,系统调用直接在CRT库中实现,因此当我调用例如的printf( “A”);这涉及到CRT的单个函数调用,其中系统调用被设置并激活.从理论上讲,这
我对系统调用的理解是,在 Linux中,系统调用机制(int 0x80或其他)被记录在案,并保证在不同的内核版本中保持稳定.使用此信息,系统调用直接在CRT库中实现,因此当我调用例如的printf( “A”);这涉及到CRT的单个函数调用,其中系统调用被设置并激活.从理论上讲,这可以通过静态编译CRT(在Linux上不常见,但有可能)进一步改进,这样即使单个函数调用也可以内联.

另一方面,Windows不记录甚至不保证系统调用机制的一致性.在Windows上进行系统调用的唯一方法是调用从CRT完成的ntdll.dll(或者其他一些* .dll),因此涉及两个函数调用.如果静态使用CRT并且函数内联(在Windows上比Linux稍微常见),我们仍然可以对ntdll.dll进行单一函数调用,这是我们无法解决的.

因此,在我看来理论上,Windows上的系统调用本身就会变慢,因为它们总是要比Linux等效函数执行一次函数调用.这种理解(以及我上面的解释)是否正确?

注意:我纯粹在理论上问这个问题.我理解在进行系统调用时(我认为总是涉及2个上下文切换 – 每个方向一个),额外函数调用的成本可能完全可以忽略不计.

在IA-32上,有两种方法可以进行系统调用:

>使用int / iret指令
>使用sysenter / sysexit说明

基于纯int / iret的系统调用需要211个CPU周期(现代处理器甚至更多). Sysenter / sysexit需要46个CPU滴答.正如您所看到的,只有一对用于系统调用的指令的执行会带来很大的开销.但是任何系统调用实现都涉及内核方面的一些工作(内核上下文的设置,调用的调度及其参数等).对于基于int / iret和sysenter / sysexit的系统调用,或多或少现实的高度优化的系统调用将花费约250和~100个CPU周期.在Linux和Windows中,它需要大约500个滴答.

同时,函数调用(基于call / ret)每个参数的成本为2-4 tics 1.

如您所见,函数调用引入的开销与系统调用成本的比较可以忽略不计.

另一方面,如果在应用程序中嵌入原始系统调用,则会使其高度依赖硬件.例如,如果没有这些指令支持的基于sysenter / sysexit的原始系统调用的应用程序将在旧PC上执行,该怎么办?此外,您的应用程序将对OS使用的系统调用约定敏感.

通常使用诸如ntdll.dll和glibc之类的库,因为它们为系统服务提供了众所周知的和硬件独立的接口,并隐藏了与场景后面的内核通信的细节.

如果使用相同的方式跨越用户/内核空间边界,Linux和Windows的系统调用成本大致相同(差异可以忽略不计).两者都尝试在每台特定机器上使用最快的方式.至少从Windows XP开始的所有现代Windows版本都是为sysenter / sysexit准备的.一些旧的和/或特定版本的Linux仍然可以使用基于int / iret的调用. x64版本的操作系统依赖于syscall / sysret指令,这些指令的作用类似于sysenter / sysexit,可作为AMD64指令集的一部分使用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读