- 主题:stackoverflow 有个比较 c++ stackful 和 stackless 协程的帖子
stackless的激活记录,不懂,也不知道怎样建立和维护。
【 在 hgoldfish 的大作中提到: 】
: stackful 协程是指之前 boost 里面实现的 boost.context, boost.fiber 等等协程方案。基本原理是保存寄存器、jmp指令、恢复寄存器。
: 而 stackless 协程是指 c++20 实现的 co_await, co_yield 这个语法。它把协程的代码变换成为另外一段 c++ 的类型,类似于 lambda 那样继承一个专门的协程类型,然后调用它的方法。
: 这里写出了两种协程的对比。
: ...................
--
FROM 221.218.61.*
stackfull,stack的空间占用,类似多线程。
如果1百万携程,空间占用是很恐怖的。
可以考虑stack池,对应与线程池的设想。
实现过一个,还行。
【 在 hgoldfish 的大作中提到: 】
: stackful 协程是指之前 boost 里面实现的 boost.context, boost.fiber 等等协程方案。基本原理是保存寄存器、jmp指令、恢复寄存器。
: 而 stackless 协程是指 c++20 实现的 co_await, co_yield 这个语法。它把协程的代码变换成为另外一段 c++ 的类型,类似于 lambda 那样继承一个专门的协程类型,然后调用它的方法。
: 这里写出了两种协程的对比。
: ...................
--
修改:ylh0315 FROM 221.218.61.*
FROM 221.218.61.*
自增栈可以 用mmap就行,我也是这么用,自顶向下,自增。
【 在 hgoldfish 的大作中提到: 】
: 空间占用不严重。因为现在 linux/openbsd 等现代发行版都早就实现了自动增长的栈。一开始只给你 4KB,随着协程函数的运行才会继续增长。
: 所以你一次性创建 1m 协程,也只会占用 4GB 的内存空间。
: Windows 也有这个功能,但我现在还没有找到哪个 API 可以创建这种自动增长的栈内存。但我知道 Windows 确实是有实现的。因为 CreateFiber() 这个函数有这个功能。
: ...................
--
FROM 221.218.61.*
但是,这1M协程,早晚都会投入工作,都投入了,内存占用可观。
因为是中间件,用户可以把任何第三方应用插进来,你无法预估栈用量。
【 在 ylh0315 的大作中提到: 】
: 自增栈可以 用mmap就行,我也是这么用,自顶向下,自增。
--
修改:ylh0315 FROM 221.218.61.*
FROM 221.218.61.*
我就是不懂stackless怎么玩栈。
我是用stackfull,当然我也没处理1m协程,大概处理过1万多点,内存已经很可观了。
后来才弄的栈池。
【 在 hgoldfish 的大作中提到: 】
: 怎么能这么想呢。stackless 的协程都投入工作,也得占用那个内存啊。而且因为 stackless 做同一件事的内存开销更大,需要不断地在堆里面分配内存,最终占用的内存说不定还会多很多呢。
:
--
修改:ylh0315 FROM 221.218.61.*
FROM 221.218.61.*
状态机得自己弄?自己在状态机里搞个栈,切换时自己弄?
协程每次激活,和挂起,都得自己处理这个栈?
【 在 ensonmj 的大作中提到: 】
: stackless不用栈,变量在状态机里面,编译器计算需要分配多大空间
--
FROM 221.218.61.*
我的一个第三方函数需要6m内存。这是在静态测试时测出来的。(若干年后,感觉与这个有关系:
https://www.newsmth.net/nForum/#!article/CPlusPlus/426083)
用的stackfull。就算自增栈,也迅速占用。
【 在 hgoldfish 的大作中提到: 】
: 不应该啊。我跑过测试,一万个协程根本没用掉啥内存。可能是因为我每个协程的调用路径都非常短吧。
: c++20 stackless 协程就是把程序拿出来变换,把每个 async 函数变成一个这样的类型:
: struct Coroutine@main_cpp#l203 {
: ...................
--
修改:ylh0315 FROM 221.218.61.*
FROM 221.218.61.*
是的,如果做协程框架中间件让别人来用,不能限制别人呀。
我只能屈服,搞了一个栈池。只用了2×线程数的栈。(32核32线程,1万协程,1w客户端,64栈)
一个线程池/多协程/栈池的方案。
我只负责调度协程资源,然后调用用户函数,用户函数干了啥我不晓得。
我不会用stackless,只能用stackfull。
人家就是用我的框架,你是啥协程人家不管,能把我函数运行起来就行。
【 在 hgoldfish 的大作中提到: 】
: 那是你这个第三方函数的问题。不关协程的事。你非要每个协程里面运行一个 Scrypt 算法高纳德过来也没办法啊。
:
--
修改:ylh0315 FROM 221.218.61.*
FROM 221.218.61.*
说得对。就是这样的。
【 在 hgoldfish 的大作中提到: 】
: stackful 协程一般是在创建协程的时候申请内存的啊。如果优化得好的话,前一个协程释放的内存可以给下一个协程使用,应该是反而减少了内存操作,而且因为协程里面运行的函数都可以方便地从栈里面申请内存,应该能够有效地提高内存数据的局部性。
: 我感觉应该是你们怎么用错了。
:
--
FROM 221.218.61.*
我设计的高频交易架构是这样:
服务器多核多线程,TPC模式,每个链接一个线程。多台服务器。服务器要处理数据库业务,只能使用简单的多线程模式。
加一个管理器,对多台服务器设置连接池。对每台服务器有限个链接(服务器有限个线程)。对多个服务器进行负载均衡和容错。
管理器采用线程池模式,M:N,M个客户端,N个线程。
一般M上万,N等于核数。
由于N要处理两边的IO(客户端的请求转到服务器,服务器的应答返回客户端),所以要用到异步。
于是有M个协程,N个线程。多线程协程,不知道ASIO框架能解决这个问题否。
这个架构,对单个任务而言,延迟比较大,在百微秒级别。
但是并行度比较好,总的系统吞吐量很大,适合交易事务处理。
总的交易吞吐量,取决于服务器数,总核数,后台数据库引擎的处理能力。
海量客户端-----交易管理器---多个服务器---数据库(RAC)
交易压力由管理器承担,超过服务器处理能力的请求在此排队。
客户端不接触数据库,只发出业务请求,并得到结果。即,数据库不对外,安全。
外部攻击的话,只能攻击管理器,那里没有数据,是保证系统数据安全的。它的抗攻击能力极强。即使被攻塌,重新启动也很快。
如果数据库被攻塌,要想恢复,你试试。
这是一个交易中间件。
客户端和服务器的交易软件,你自己写。
有服务接口。
中间的什么线程协程,你不要管,全透明,就当他不存在。
【 在 gfkid 的大作中提到: 】
: 好奇高频交易都是怎样的软件架构
: 似乎都是单体软件,不能搞网络间的分布式了,走网络就慢了
--
修改:ylh0315 FROM 221.218.61.*
FROM 221.218.61.*