为什么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职能的重点,因此不能将其描述为疏忽。(如果不想保留信号掩码,可以使用 setjmplongjmp

顺便说一下,ucontext_t函数在 Posix 第 6 版中被弃用,并在第 7 版中删除,因为 (1( makecontext 接口需要 C 的过时功能,这在C++中根本不可用;(2(接口很少使用;(3( 协程可以使用 Posix 线程实现。(请参阅Posix第6版中的注释。(显然,线程不是实现协程的理想机制,但依赖于过时功能的接口也不是。

相关内容

最新更新