4

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 实现者遗漏的一些低级技巧,还是这里发生了其他事情?

4

1 回答 1

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 中的注释。)(显然,线程不是实现协程的理想机制,但也不是依赖于过时特性的接口。)

于 2015-10-25T16:50:00.773 回答