Chinaunix首页 | 论坛 | 博客
  • 博客访问: 66027
  • 博文数量: 5
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 393
  • 用 户 组: 普通用户
  • 注册时间: 2014-09-11 22:32
个人简介

曾经天真的以为做IT就是研究各种先进技术;工作后才知道99%的时候做的是体力活。在迷茫和痛苦中追寻前进的路标

文章分类
文章存档

2014年(5)

我的朋友

分类: C/C++

2014-09-21 21:41:04

曾经带过一个实习生,对我说“做服务器,并行肯定比串行快,因为并行可以开100个线程一起跑,当然比串行单个线程跑要快了”

答:“线程又不是凭空就能跑得起来的,要有CPU才能让线程跑起来。串行开辟CPU个数进程,还能避免锁和线程切换的开销,不是更快吗”

又问:“那为什么大家都说并行服务器比串行服务器快呢”

是啊,为什么呢?


为什么大部分串行模式的服务器会慢

首先我们要明确一点:服务器性能是从哪里来的。

软件本身是不能创造性能的,只有硬件烧掉电能之后才能获得性能(运算能力)。也就是说,无论并行模式还是串行模式,最佳的结果就是让所有CPU满负荷运转。


并行模式的服务器能保证所有CPU满负荷运转,达到最佳性能。

而串行模式往往会睡眠,睡眠其实就是线程需要等待某个资源,无法继续运行。服务器睡眠就会导致CPU闲着没事干,性能大幅下降。


什么情况下我们的服务器会睡眠,导致CPU没事干呢?

最常见的原因是读socket时,需要等待对方处理数据和网络传输。

串行模式下会直接睡眠,而在并行模式下,我们会用epoll+非阻塞模式socket来避免等待。

睡眠可控的串行模式

并行模式通过采用epoll+非阻塞/异步io,完全解决了睡眠问题。但是并行模式也引入了各种问题:例如程序逻辑会变得复杂,例如各个地方需要加锁。

就我的开发经验来看,同一个功能采用并行模式来实现要比采用串行模式增加30%的编码时间,对于质量要求高的行业(如电商、通信),采用并行模式还要面对极其难解决的同步bug
      备注:顺带提一句,我面试过的工程师中,只有不到0.1%的人知道并发环境下内存屏障的正确用法。


有没有什么办法,既能采用串行模式开发提高开发效率,又能让CPU达到满负荷运转呢?


如果我们能保证睡眠时间占总时间比例小于x,只要启动cpu_num * 1 / x个进程或线程,就可以保证每个CPU满负荷运转

假设我能控制线程处理每个请求是10ms逻辑运算时间+90ms睡眠时间,那么只要开CPU个数*10的进程,就可以保证每个CPU都跑满,达到最佳性能。


服务器和客户端之间的socket可能长时间等待,其睡眠时间是不可控的。但是通过nginx+fastcgi的模式,我们可以让nginx负责和客户端之间的连接,当收到完整的请求数据时再把请求转给我们的fastcgi,这样就完全避免了服务器和客户端之间socket通信带来的睡眠

剩下需要估算的延时就只有fastcgi和数据库之间的访问延时,这是一个可以控制的睡眠时间。


曾经做过的一款日活跃上亿的游戏就是采用这样的串行架构实现的。性能和并行一样都达到了最佳(能让所有CPU满负荷运转),同时又免去了加锁处理同步问题的麻烦。

阅读(3068) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~