我对系统调用的理解是,在 Linux 中,系统调用机制(int 0x80 或其他)被记录下来并保证在不同的内核版本中保持稳定。使用此信息,系统调用直接在 CRT 库中实现,因此当我调用例如printf("a"); 这涉及对 CRT 的单个函数调用,系统调用在此处设置并激活。从理论上讲,这可以通过静态编译 CRT(在 Linux 上不常见,但有可能)来进一步改进,这样即使是单个函数调用也可以内联。
另一方面,Windows 不记录甚至不保证系统调用机制的一致性。在 Windows 上进行系统调用的唯一方法是调用完成的ntdll.dll(或者可能是其他一些*.dll)来自 CRT,因此涉及两个函数调用。如果静态使用 CRT 并且函数被内联(在 Windows 上比在 Linux 上更常见),我们仍然无法摆脱对 ntdll.dll 的单个函数调用。
所以在我看来,从理论上讲,Windows 上的系统调用本质上会更慢,因为它们总是比 Linux 系统调用多执行一个函数调用。这种理解(以及我上面的解释)是真的吗?
注意:我纯粹是从理论上问这个问题。我知道在进行系统调用时(我认为这总是涉及 2 个上下文切换 - 每个方向一个)额外函数调用的成本可能完全可以忽略不计。
最佳答案
在 IA-32 上有两种方式进行系统调用:
纯基于 int/iret 的系统调用需要 211 个 CPU 周期(在现代处理器上甚至更多)。 Sysenter/sysexit 需要 46 个 CPU 滴答。如您所见,仅执行一对用于系统调用的指令会引入大量开销。但是任何系统调用的实现都涉及内核端的一些工作(内核上下文的设置、调用及其参数的调度等)。对于基于 int/iret 和 sysenter/sysexit 的系统调用,或多或少现实的高度优化的系统调用分别需要约 250 和 ~100 个 CPU 周期。在 Linux 和 Windows 中,大约需要 500 个滴答。
同时,函数调用(基于 call/ret)每个参数的成本为 2-4 tic + 1。
如您所见,与系统调用成本相比,函数调用引入的开销可以忽略不计。
另一方面,如果您在应用程序中嵌入原始系统调用,您将使其高度依赖于硬件。例如,如果您的应用程序具有基于嵌入式 sysenter/sysexit 的原始系统调用,将在没有这些指令支持的旧 PC 上执行怎么办?此外,您的应用程序将对操作系统使用的系统调用约定敏感。
像ntdll.dll和glibc这样的库很常用,因为它们为系统服务提供了众所周知的和硬件无关的接口(interface),并隐藏了与内核通信的细节。
如果使用相同的跨越用户/内核空间边界的方式,Linux 和 Windows 的系统调用成本大致相同(差异可以忽略不计)。两者都试图在每台特定机器上使用最快的方式。至少从 Windows XP 开始的所有现代 Windows 版本都为 sysenter/sysexit 做好了准备。一些旧的和/或特定版本的 Linux 仍然可以使用基于 int/iret 的调用。 x64 版本的操作系统依赖于 syscall/sysret 指令,它们的工作方式类似于 sysenter/sysexit,并且作为 AMD64 指令集的一部分提供。
关于linux - Windows 上的系统调用天生就比 Linux 慢吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22069060/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注