为什么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 | +----------+----------------------+-------------------+-------------------+----------------+ 

[链接]

我相信这些实验的源代码托管在GitHub上 。

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

Boost文档指出了为什么Boost.context比不推荐使用的ucontext_t接口更快。 在基本原理部分 ,您会发现这个重要说明:

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

并且,与其他API中的 makecontext进行比较:

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

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

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