C++ 为什么ucontext的开销如此之高?

C++ 为什么ucontext的开销如此之高?,c++,c,boost,ucontext,C++,C,Boost,Ucontext,Boost v1.59中Boost.Context的文档报告了以下性能比较结果: +----------+----------------------+-------------------+-------------------+----------------+ | Platform | ucontext_t | fcontext_t | execution_context | windows fibers | +----------+-----------

Boost v1.59中Boost.Context的文档报告了以下性能比较结果:

+----------+----------------------+-------------------+-------------------+----------------+
| Platform |      ucontext_t      |    fcontext_t     | execution_context | windows fibers |
+----------+----------------------+-------------------+-------------------+----------------+
| i386     | 708 ns / 754 cycles  | 37 ns / 37 cycles | ns / cycles       | ns / cycles    |
| x86_64   | 547 ns / 1433 cycles | 8 ns / 23 cycles  | 16 ns / 46 cycles | ns / cycles    |
+----------+----------------------+-------------------+-------------------+----------------+

我相信


我的问题是,为什么Boost库实现的开销比Boost库实现的开销高20倍?我看不出有什么明显的原因会有如此大的差异。Boost实现是否使用了ucontext实现者错过的一些低级技巧,或者这里发生了其他事情?

Boost文档说明了Boost.context比不推荐的ucontext\t接口更快的原因。在中,您将发现以下重要注意事项:

注 上下文开关不会在UNIX系统上保留信号掩码

与中的
makecontext
相比:

ucontext\u t在上下文切换之间保留信号掩码,这涉及到消耗大量CPU周期的系统调用

如前所述,
swapcontext
确实保留了信号掩码,这需要一个系统调用和由此产生的所有开销。由于这正是
ucontext\u t
函数的要点,因此不能将其描述为疏忽。(如果不想保留信号掩码,可以使用
setjmp
longjmp


顺便说一下, UCONTXEXT 函数在POSIX版6中被删去,在版本7中被删除,因为(1)<代码> MakEngEngest/<代码>接口要求C的过时特性,在C++中是完全不可用的。(2) 接口很少使用;(3)可以使用Posix线程实现协同路由。(显然,线程不是实现协同程序的理想机制,但也不是依赖于过时的功能的接口。)< /P> @奥拉夫-我添加了C标记,因为<代码> uWrime>代码>是用C实现的,而不是C++。为什么要删除它?没有显示支持此操作的代码。现场规则要求提供一个独立的问题。如果没有一个语句,你必须假设你是在比较苹果和苹果(C++和C++),而不是桔子。但是在你的评论后,它看起来像后者(C vs C++比较)。@奥拉夫-也没有代码支持这是一个C++问题,但是你可以从我谈论Boost的事实推断出。类似地,如果你知道什么是ucontext,那么你就可以推断这也与C有关。如果你将鼠标悬停在ucontext标志上,你会看到它是一个C库(ucontext.h)…这是一个非常好的观察(+1)!我知道POSIX标准在技术上不推荐使用它,但由于没有替代品,它仍然在我检查过的每个平台上实现。(这种不赞成实际上就是为什么我一开始就把Boost.Context作为一种替代方案。我只是希望它能作为一个独立的C库来实现…)Posix edition 6中的链接说明并不是说可以使用Posix线程来实现协程,它建议开发人员只使用Posix线程,而不完全使用协程。非常令人失望的是,他们选择不推荐整个接口,而不是像Posix线程那样简单地更新它以使用

void*
,因为“现在很少有应用程序使用*context()例程”@noam:如果你将基于协程的应用程序转换为使用线程,那么你肯定已经用线程实现了你的协同程序,不是吗?但在我看来,这只是一个次要的语义问题。如果你真的觉得不舒服,我会改的。我不想为委员会的行为辩护,但我怀疑他们删除了接口,因为他们无法在实现之间就如何修复它们达成共识。很容易说,“如果我是独裁者,这就是我要强加的”:-,但Posix是一个不稳定的联盟,而不是独裁者,这限制了它的强制执行能力。我认为协同程序是指具体的用户级非先发制人线程,所以“如果你用线程实现了你的应用程序,那么你就用线程取代了协同程序”,但我明白你是如何把它理解为一件不同的事情的。(idk,如果严格来说,其中一种含义更为正确)。请随意保留答案,我只是感到失望,因为我将您的答案解释为有一种方法可以使用Posix线程使用户级非抢占线程。