为什么ucontext具有如此高的开销? [英] Why does ucontext have such high overhead?

查看:261
本文介绍了为什么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上./p>

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

解决方案

Boost文档指出了为什么Boost.context比不推荐使用的ucontext_t接口要快.在理论部分中,您会发现以下重要提示:

注意 上下文切换不会在UNIX系统上保留信号掩码.

,并且与makecontext进行比较" rel ="nofollow">其他API :

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

如前所述,swapcontext确实保留了信号掩码,这需要系统调用以及随之而来的所有开销.由于这正是ucontext_t函数的要点,因此不能将其描述为疏忽大意. (如果不想保留信号掩码,则可以使用setjmplongjmp.)

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

The documentation for Boost.Context in Boost v1.59 reports the following performance comparison results:

+----------+----------------------+-------------------+-------------------+----------------+
| 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    |
+----------+----------------------+-------------------+-------------------+----------------+

[link]

I believe the source code for these experiments is hosted on GitHub.

My question is, why is the overhead for ucontext 20x higher than the Boost library's implementation? I can't see any obvious reason why there would be such a big difference. Is the Boost implementation using some low-level trick that the ucontext implementers missed, or is something else happening here?

解决方案

The Boost documentation indicates why Boost.context is faster than the deprecated ucontext_t interfaces. In the Rationale section, you'll find this important note:

Note Context switches do not preserve the signal mask on UNIX systems.

and, in the comparison with makecontext in Other APIs:

ucontext_t preserves signal mask between context switches which involves system calls consuming a lot of CPU cycles.

As indicated, swapcontext does preserve the signal mask, which requires a syscall and all the overhead that entails. Since that was precisely the point of the ucontext_t functions, it cannot be described as an oversight. (If you don't want to preserve the signal mask, you can use setjmp and longjmp.)

By the way, the ucontext_t functions were deprecated in Posix edition 6 and removed in edition 7, because (1) the makecontextinterface requires an obsolescent feature of C, which is not available at all in C++; (2) the interfaces are rarely used; and (3) coroutines can be implemented using Posix threads. (See the note in Posix edition 6.) (Clearly, threads are not an ideal mechanism for implementing coroutines, but neither is an interface which relies on an obsolescent feature.)

这篇关于为什么ucontext具有如此高的开销?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆