杂志的官方blog RSS: http://blog.csdn.net/emag_cpp/Rss.aspx
文章:重负载Telnet BBS 系统优化和维护经验谈
一:IO优化
a) 尽量使用shm 等IPC 手段而不是文件
这一点在我们的系统里核心部分有比较充分考虑的(用了一个G以上的共享内存),用shm取代数据库或文件。
甚至flock 这样看起来不会造成太多IO 的同步操作都应该尽量避免,原因是flock 需要先open文件,而open 文件需要找到i 节点,因此会占用文件系统的inode 缓存空间,可能造成其他IO 操作的性能降低。在很多情况下面需要的只是一个跨进程的mutex,可以使用0/1 信号灯来实现
在我们的系统里频繁的使用了记录锁(用的是fcntl),从逻辑上讲无法避免(必须实现读写锁).是否对性能有所影响,目前没有统计.pthread_rwlock系列函数是线程级的,不太适用.
b) 使用应用层缓存。
这一点有考虑.把数据完全或动态的从文件或数据库加载到内存里,在实时业务使用.实行中命中率还可以,但由于实现原因,面临着一些数据同步问题.
c) 尽量减少关键IO 数据结构的大小
我们的系统实时任务部分虽然没有频繁的磁盘操作,但系统各模块间传递的数据块有一些臃余,原因是结构体设计主要考虑了通用性,使用了union或大数据缓冲定义
.
d) 避免在同一目录下放过多文件或者使用合适的文件系统
暂时没有这方面的问题.
e) 根据系统的访问模式选择适合的硬件配置和系统参数
这部分问题不大,用的是都是很强的机器并将系统内核参数调整得很充裕.
2: 内存使用优化
a) 尽量避免动态初始化常量,使用const 说明将变量和常量区分开来。
"动态初始化常量"的提法比较奇怪的说....不过一般来说在我们系统里作为常量,都会被声明为全局的,应该不会有所谓"动态初始化"的问题.
b) 减小内存的峰值使用,特别是堆栈中内存
文章中提到尽量少定义或malloc大块的缓冲区,这一点是必须注意的.在我们的系统里动辄定义或malloc(并初始化&free)上兆甚至几兆,两位数兆的地方都有.
c) 如有可能,尽量使用shm 来保证页面一定会被多个进程共享。
这一点已经有充分考虑.
3: CPU 优化
a) 使用针对硬件优化的编译器
推荐编译时候针对特定CPU 指令集优化并且打开跨文件优化选项(-ipo)
对于编译器和编译过程目前的研究比较少,基本上只用了gcc的常用选项,而且是调试模式(-g)!!库都是静态连接,导致可执行文件庞大,加载缓慢.
b)用单独进程来初始化和维护共享内容,避免出现竞争导致逻辑错误
在初始化共享内容时,有些环节在保护和互斥上作的还不够.极端情况下容易出现问题.
c)序列化容易导致负载上升的行为
目前对这一点重视还不够,除了技术因素,还有业务流瓶颈和冲突上的分析都不够.
d) 尽量减少信号的使用
系统在一些环节上过度和不恰当的使用了信号,但目前正在逐步的尽量减少类似代码.
e) 对于大范围IO 读取操作,使用mmap 调用
对于庞大的日记分析操作,可以考虑用mmap优化之.
使用mmap 操作比传统的read 操作好处是减少了一次内核态到用户态的拷贝。但并不适用于有写入的情况,因为mmap 写盘的时候是以页为单位进行操作,页中只要有一个字节被改写,就要往磁盘上面写整个页面的数据,
另外的几篇文章
<C10K 问题>: 比较全面的介绍了并发服务器的各种响应模式.比我之前写的一篇服务器编程笔记强多了.
<从异步谈起>:也是比较全面的介绍异步操作技巧的一篇文章,但重点是windows平台上的overlapp操作.
<可变参数学习笔记>,对c/c++编程里比较微妙的var_arg/var_list有比较好的讨论研究,但我没有尝试其代码.
csdn这批e_mag内容质量还比较不错,值得经常看看.