为什么ucontext有这么高的开销?

时间:2015-10-25 16:13:43

标签: c++ c boost ucontext

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    |
+----------+----------------------+-------------------+-------------------+----------------+

[link]

我相信the source code for these experiments is hosted on GitHub

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

1 个答案:

答案 0 :(得分:2)

Boost文档指出为什么Boost.context比不推荐使用的ucontext_t接口更快。在Rationale section中,您会发现这个重要说明:

  

请注意   上下文切换不保留UNIX系统上的信号掩码。

,并与Other APIs中的makecontext进行比较:

  

ucontext_t在上下文切换之间保留信号掩码,这涉及系统调用消耗大量CPU周期。

如上所述,swapcontext确实保留了信号掩码,这需要系统调用以及所需的所有开销。由于这正是ucontext_t函数的要点,因此不能将其描述为疏忽。 (如果您不想保留信号掩码,可以使用setjmplongjmp。)

顺便说一句,ucontext_t函数在Posix第6版中已弃用,在第7版中已删除,因为(1)makecontext接口需要C的过时功能,但根本不可用在C ++中; (2)接口很少使用; (3)协程可以使用Posix线程实现。 (参见note in Posix edition 6。)(显然,线程不是实现协同程序的理想机制,但它们都不依赖于过时的功能。)