最近在测试简单的轻量级线程调度器。从fiber转换到generator,性能是提升了不少,但却在意想不到的地方出现了瓶颈。 在generator本身切换性能测试时,发现它性能非常高,大概单线程里面每秒切换有2亿次以上,比fiber的200-400万次有了质的提高。但是在实现了一个简单的调度器以后,发现性能急骤下降,到了每秒千万次,实现方式是使用标准库提供的list容器。 在测试了c++标准库的std::list和c#的几个list容器以后,发现它们性能都非常低,每秒仅能处理上千万次尾部添加和头部删除操作。简单分析后可以确认,性能降低是由于频繁的分配释放引起的,改用g++的ext/poll_ ...
前面说地Generator编写并发程序的优势,当然它本身没有这种能力,需要为它编写调度程序。 今天抽点时间写了个简单的,还是满好玩的,它可以调度多个“友好”的并发任务,包括: 1、用户自己编写的适时交出控制权的过程 2、网络IO 由于对C#不是很熟,所以写的可能比较难看,而且IO也只支持网络,有兴趣的可以研究改进一下,比如把它改成SMP版本,增加Actor模型,处理更多的IO模式等。 实现方式基本上是从IoLanguage里面抄过来的,我已经用它编写过Ruby/C++/D/C#版本,当然目前仅限于测试它的切换性能。 好消息是如果你实现得比较好,C#版本性能完全可以超过Erlang,Ru ...
一直没搞清云计算和网格计算的差别,为什么就提出个新词了呢? 通过对Amazon的Google的观察,发现这两家公司产品方向的一些共同点。 1、软件即服务 Google App Engine和Amazon SimpleDB/S3都是提供服务的,类似的例子还有最近比较火的各种开放接口。 2、应用容器,自动部署,超强的扩展能力 Google App Engine更能体现这点。由于开放的所有接口都是调用服务,应用运行的容器本身完全不需要保存任何状态,它只需要有强劲的CPU、内存和网络设备,任何时候都可以把服务横向扩展到多台服务器上。 3、后台技术 分布式文件系统,分布式DB,都需要提供超强的性 ...
2008-04-09

Generator

几种并发编程模型开销(从大到小): Process > Thread > Coroutine > Generator == Callback 从对机器的并行利用来说,却是完全相反的。 Process可以部署在不同机器上; Thread需要在Process里面,往往是很多Thread在一个Process里面,它对多CPU利用还是比较充分的; Coroutine在Thread里面运行,要利用多CPU,需要实现调度器; Generator算是一种带有状态的Callback,或者是对象化的Callback,它们也需要运行在Thread里面,要利用多CPU,需要实现调度器; 为什么Generat ...
  • 13:46
  • 浏览 (120)
  • 评论 (0)
  • 分类: D
先总结一下。 线程是最容易编写的并发方式,操作系统也提供了最好的支持;协程可以做到更强的并发能力,但需要实现调度器;回调是开销最小的,它本来不是特别为并发来设计的,它是通用的异步化操作的实现模型。 注意线程和协程本身也是使用异步来模拟同步,线程由操作系统来模拟,协程由用户级调度器模拟。模拟的过程是:发起事件请求、挂起当前执行过程(线程或协程)、响应事件请求、恢复挂起的执行过程。回调没有这么复杂,你需要自己把连续的执行过程分解成多步操作。 线程就不讨论了,用起来比较简单;协程之前简单研究了一下,切换开销比线程有很大改进,但还是有点大,用作IO事件调度还可以,粒度更小的操作就显得开销过大了, ...
2008-03-31

结合Coroutine和Callback

关键字: coroutine callback
Coroutine切换成本相对还是比较高的,把一个并发程序改成Coroutine实现性能上可能有比较大的损失。Coroutine切换主要是大量寄存器压栈和弹栈,栈切换也会影响到cache。目前C/C++大量使用的是回调方式,比如win32窗口编程、libevent等,优点是高效,函数调用成本是很低的,也没有栈切换,缺点是不如Coroutine这样连贯。有没有方法让它具有两者的优点呢?有Coroutine连贯的过程,也有Callback的高效?还是考虑这个简单的例子: (本文代码使用D语法,但并没有编译测试) void client_loop(int fd) { while(tru ...
2008-03-29

linux WEB服务器故障两则,兼谈分布式系统

关键字: linux strace lsof 死锁 分布式
前段时间公司网站出过两次事故,前台跑PHP的Apache进程大量死锁,造成服务器无负载但不能提供服务,不断重启服务也未能解决问题,但过几小时后自动恢复。这些系统已经稳定运行数月之久,虽然不断有升级但没有出现这类情况。 一周后第二次出现相同情况时公司组织人力进行了排查,没有发现问题。由于没有WEB机器登录权限,于是让运维同事做了这些操作来查找原因: 1、strace -p xxxx查看任意httpd进程,查看进程运行状态。如果没有阻塞在futex上,换一个进程再查看。 这一步一般可以查出很多原因,比如死循环,如果strace没有显示一个系统调用正在进行,一般是限入无终结条件的死循环,这种情况 ...
2008-03-13

C和Erlang轻量级线程性能

关键字: erlang coroutine lightweight process thread performance
简单比较了一下ucontext和Erlang的进程切换效率,在我的机器上ucontext每秒可以完成90万次切换,Erlang则要快得多,每秒可以完成412万次切换,这个性能比较和之前shootout上的测试相近。 效率差这么多是可以预见的,C的轻量级线程实现都是栈切换的,要完成寄存器保存和加载,只是不需要经过系统调度。相比之下其它语言的轻量级线程切换通常不是C栈切换,开销要小得多。 有这么大的差距是不是Erlang就有很大的性能优势呢?我觉得不是。Erlang为了保证实时性,把进程调度的粒度设置到函数调用这个级别上,复杂的应用中很容易导致过多的切换;而C实现则是由程序员自己找准时机来切换 ...
2008-02-18

Coroutine在并发程序中的应用

关键字: 并发 协程 coroutine
理论知识太少,表达能力太差,简单发点自己的总结,有意见请不要给我面子 下面所列的几个场景只是我接触过的几个,并不是最适合用来说明Coroutine应用的,如果你有更好的例子或是反对意见,我希望听到不同的声音。我对Coroutine的理解只是皮毛,并没有大规模应用过,也想听到一些应用经验。 首先我得承认我对于并发、异步、并行、分布式这些概念毫无兴趣,我甚至讨厌理论相关的东西,我也不能给它们做出准确的解释,我只是不断寻找更简单的编码方式。 并发应用场景 场景一:基于状态机的并发协议处理 状态机通常用于把一段处理过程分解成有限个稳定的状态,在处理过程中在这些状态间切换。举一个简单的协议例 ...
  • 21:20
  • 浏览 (767)
  • 评论 (15)
2008-02-16

Erlang/IoLanguage/Ruby

关键字: 语言比较
最近下决心和Erlang说再见了,想了很多,也用了一段时间,断断续续数落过几次Erlang的优缺点,看得不深,权当我是瞎说。简单整理一下: 优点:高并发、分布式、资源管理、高效率(和其它动态语言比较)、热升级、自动并行 缺点:语言抽象能力不强、语言扩展能力不强、FP让大多数人不适应、和C库交互不好 有一段时间我打算自己做一套类似的框架,使用coroutine,虽然我测试过的coroutine库都不如Erlang高效(注1),但C编写处理代码比Erlang高效多了,完全可以弥补。和C库的交互可以更自然地实现。我不打算做个多线程的调度器,因为有太多第三方库需要线程池、异步IO去完成的操作,这些 ...
qiezi
搜索本博客
存档
最新评论