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 |
+----------+----------------------+-------------------+-------------------+----------------+
我相信the source code for these experiments is hosted on GitHub。
我的问题是,为什么ucontext的开销比Boost库的实现高20倍?我看不出有什么明显的原因会有这么大的差异。 Boost实现是否使用了ucontext实现者错过的一些低级技巧,或者是否有其他事情发生在这里?
答案 0 :(得分:2)
Boost文档指出为什么Boost.context比不推荐使用的ucontext_t
接口更快。在Rationale section中,您会发现这个重要说明:
请注意 上下文切换不保留UNIX系统上的信号掩码。
,并与Other APIs中的makecontext
进行比较:
ucontext_t在上下文切换之间保留信号掩码,这涉及系统调用消耗大量CPU周期。
如上所述,swapcontext
确实保留了信号掩码,这需要系统调用以及所需的所有开销。由于这正是ucontext_t
函数的要点,因此不能将其描述为疏忽。 (如果您不想保留信号掩码,可以使用setjmp
和longjmp
。)
顺便说一句,ucontext_t
函数在Posix第6版中已弃用,在第7版中已删除,因为(1)makecontext
接口需要C的过时功能,但根本不可用在C ++中; (2)接口很少使用; (3)协程可以使用Posix线程实现。 (参见note in Posix edition 6。)(显然,线程不是实现协同程序的理想机制,但它们都不依赖于过时的功能。)