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

Dao*_*Wen 4 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    |
+----------+----------------------+-------------------+-------------------+----------------+
Run Code Online (Sandbox Code Playgroud)

[关联]

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

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

ric*_*ici 7

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

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

并且,在比较makecontext其他API

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

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

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