tbox之前提供的stackfull协程库,虽然切换效率已经非常高了,但是由于每个协程都需要维护一个独立的堆栈, 内存空间利用率不是很高,在并发量非常大的时候,内存使用量会相当大。
之前考虑过采用stacksegment方式进行内存优化,实现动态增涨,但是这样对性能还是有一定的影响,暂时不去考虑了。
最近参考了下boost和protothreads的stackless协程实现,这种方式虽然易用性和灵活性上受到了很多限制,但是对切换效率和内存利用率的提升效果还是非常明显的。。
因此,我在tbox里面也加上了对stackless协程的支持,在切换原语上参考了protothreads的实现,接口封装上参考了boost的设计,使得更加可读易用
先晒段实际的接口使用代码:
tb_lo_coroutine_enter(coroutine)
{
while (1)
{
tb_lo_coroutine_yield();
}
}
然后实测对比了下:
* 切换性能在macosx上比tbox的stackfull版本提升了5-6倍,1000w次切换只需要40ms
* 每个协程的内存占用也减少到了只有固定几十个bytes
为了进一步裁剪tbox,更好的适配嵌入式开发平台,tbox新增了--micro=y
的微模块编译选项
如果启用此编译选项,那么只会编译tbox里面较轻量的一些模块,是的编译后的库大小,尽量保证在64K左右。
先来讲讲一些跟库大小相关的编译选项:
* `--smallest=y`: 通用平台,最小编译模式,会禁用所有第三方依赖库,禁用所有扩展模块,启用最小化编译优化(库内部也会尽可能节省内存使用)
* `--micro=y`: 专门针对嵌入式平台设计,仅编译最为轻量的一些模块,启用最小化编译优化(有可能会包含一些可选组件)
smallest和micro的区别在于,即使启用了smallest禁用所有扩展模块,但是还是会内置比micro更多的常用组件用于日常基础开发 而micro是专门为嵌入式平台设计,内置的默认组件更加的精简,一些重量级的模块就不放置进去了
因此如果要编译最小tbox库,只需要执行下面的配置:
$ xmake f --micro=y
$ xmake
如果要在micro下面启用协程支持,只需要:
$ xmake f --micro=y --coroutine=y
$ xmake
进行编译就行了,一般库大小会控制在64K左右,目前内置模块还不是很多,后续会进一步精简优化,使其在64K内包含更多使用的模块。
目前微内核编译模式支持的一些模块有:
list_entry
/single_list_entry
单双链容器(比list
/single_list
更加轻量,外置式,不会维护对象内存)__tb_thread_local__
线程局部存储支持list_entry
/single_list_entry
)关于micro编译的更多支持模块列表,见micro.lua
后续在保持库大小不增加的前提下,还会增加更多轻量级模块(例如:定时器、更多的容器和算法支持。。)
最近对xmake.lua的工程描述语法进行了增强,现已可以同时支持两种不同语法风格。
这种是xmake经典的设置风格,例如:
target("test")
set_kind("static")
add_defines("DEBUG")
add_files("src/*.c", "test/*.cpp")
这种是xmake最近新加的风格,例如:
target
{
name = "test",
defines = "DEBUG",
files = {"src/*.c", "test/*.cpp"}
}
在分析了各大开源协程库实现后,最终选择参考boost.context的汇编实现,来写tbox的切换内核。
在这过程中,我对boost各个架构平台下的context切换,都进行了分析和测试。
在macosx i386和mips平台上实现协程切换时,发现boost那套汇编实现是有问题的,如果放到tbox切换demo上运行,会直接挂掉。
在分析这两个架构上,boost.context切换实现问题,这边先贴下tbox上的context切换demo,方便之后的讲解:
最近在做ios app的企业测试包,需要频繁打包分发给测试,因此将编译完的.app打包成ipa单独分发出去,这里调研下几种打包方案:
为了方便日常ios app打包程ipa,觉得可以把这个脚本放到xmake中去,作为一个小插件提供,也是个不错的方式。
因此顺手在xmake里面加了这么一个ipa to app的小插件,进行快速打包,使用方式如下:
$ xmake app2ipa --icon=Icon.png /xxx/xxx.app
icon参数指定的是app的主图标,用作iTunesArtwork,目前还不能自动设置,需要手动指定哦。。
后面只需要传入需要打包的xxx.app的路径就可以了,默认ipa会载同目录下生成/xxx/xxx.ipa,也可以通过--ipa/-o
指定输出路径。
注:这只是个小工具,目前还不支持自动修改签名,有兴趣的同学,可以提pr上来,加上这个功能哦。