Goroutine与Libtask协程切换性能比较

gerry · · 5328 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

##Goroutine与Libtask协程切换性能比较 ##Libtask Libtask是一个非常轻量级的C语言协程库,作者是大名鼎鼎的拉斯.考克斯,也是Go语言的作者之一。Libtask的实现原理也很简单,主要是利用系统调用如:getcontext、setcontext(注:不同的操作系统有不同的系统调用)封装成makecontext、swapcontext两个函数,利用这两个函数实现在单个线程中执行多个task,协程上下文切换非常轻量,因为是在同一个线程中,所以只需要保存和设置SP和PC就可实现上下文切换。 ###Goroutine Goroutine的实现应该有参考Libtask,主体思想都差不多,只不过Goroutine扩展到可以支持多核处理器,系统调用、IO等阻塞都会移到一个独立的线程中,释放阻塞线程,以便其他协程能够继续处理;Libtask也支持异步IO和同步IO,同步IO会阻塞线程,异步IO不会阻塞线程,并且多个异步非阻塞IO会放到同一个异步协程处理,很遗憾Libtask目前仅支持poll,暂不支持epoll,不过可以自己实现。 ###对比测试 为了对比协程切换性能,设计一个简单的测试用例,分别切换100000000次,比较运行时间。 ###测试环境 硬件:MacBook Pro, 2.5 GHz Intel Core i7,16 GB 1600 MHz DDR3 OS: OS X EI Captain Go编译器版本:1.6.2 C编译器版本:clang-703.0.29 + LLVM ####GO测试代码: ``` package main import( "fmt" "time" "runtime" ) const TOTAL_COUNTS = 100000000 func test(c chan int) { count := 0 for { count++ if count > TOTAL_COUNTS { c <- 1 break } runtime.Gosched() } } func main() { runtime.GOMAXPROCS(1) c := make(chan int, 0) startTime := time.Now() go test(c) <-c fmt.Println("USEAGE TIME:", time.Since(startTime)) } ``` ####Libtask测试代码 ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <task.h> const int STACK_32K = 32678; const int TOTAL_COUNTS = 100000000; struct timeval tv_begin, tv_end; void test() { int count = 0; while(1) { count++; if (count > TOTAL_COUNTS) { gettimeofday(&tv_end, NULL); int time_usage = (tv_end.tv_sec - tv_begin.tv_sec) * 1000 + (tv_end.tv_usec- tv_begin.tv_usec)/1000; printf("USAGE TIME: %d\n", time_usage); break; } taskyield(); } }void taskmain(int argc, char** args) { gettimeofday(&tv_begin, NULL); taskcreate(test, NULL, STACK_32K); } ``` ###测试结果 libtask: 10412ms Goroutine: 10965ms ###结果分析 从结果来看基本相当,Goroutine只是略微慢些,其原因是Go语言有Runtime和GC,执行效率本身就略慢于C语言;另外Goroutine支持多核,有多个处理器,有线程池,那么诸如任务队列、Channel必然会存在竞争,有竞争必然用到锁,这会进一步影响其性能。 综上,Goroutine的协程切换效率非常棒,与单线程的Libtask相差无几,但是Goroutine可以利用多核处理器来提高并发,微量的性能影响也就可以忽略不计了。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

5328 次点击  
加入收藏 微博
1 回复  |  直到 2016-06-09 13:37:01
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传