DongHao: 03 2011存档

intel

上周五下午去参加了intel的软件开发大会。我参加过去年的大会,那时候强调的是TBB,这次强调的是并行优化。
先是屠鹏先生介绍Cilk,不知道这门语言在业界怎么样,反正我是第一次了解。用cilk写出来的Fibonacci算法如下:

int fib(int n) {
if (n<2) return n;
int x = cilk_spawn fib(n-1);
int y = fib(n-2);
cilk_sync;
return x+y;
}

上面的cilk_spawn表示“指定的子函数可与父调用方法并行执行”,而cilk_sync表示“在所有衍生的子函数返回之前,控制不能通过这一点“,其实跟pthread里的pthread_creaet和pthread_join有点相似。
还有就是for循环:

for(int i=0; i<8; i++) {
do_work(i);
}

变成

cilk_for(int i=0; i<8; i) {
do_work(i);
}

这样就是cilk就可以把循环变成并行的,把do_work变成8个任务,分配给多个核。cilk还支持方便的矩阵运算。
这是并行计算里典型的“语言级”的解决方案,个人感觉相比TBB这类“库级”解决方案,平台兼容性和移植性会比较差。何况cilk的强项——矩阵运算/数值运算我在公司几乎从未遇到。

然后是一位仁兄演示Vtune的使用,客观的说,讲得有点琐碎,就看见鼠标飞舞,在界面上乱点,满屏红条条绿条条,眼晕。有空还是自己下载一个evaluation版来试用吧。

之后是一些优化案例,我才知道intel有一堆团队专门给大客户做应用程序的优化,想来这活儿八成比较枯燥,但是成就感应该还不错。
其中一个案例,用至强5600系列机器自带的一些指令来优化AES加密,给一个网游公司提速了不少;还可以用SSE指令来帮忙优化数据压缩的速度等,如下:

intel,AES

给我印象最深的是陈健先生的演讲,他的速度很快,思维敏捷。主讲内容摘录如下:
方法一:尽可能使用最新版的intel编译器
1. Intel c/c++ Composer 12.0
2. 使用编译选项
2.1 针对通用的性能优化:-O3 -fast
2.2 针对快速除法和开方:-no-prec-dev / -no-prec-sqrt
2.3 针对向量化:       -xS, -xT(Core), -xP(NetBurst)
2.4 针对CacheMiss:   -fno-alias
2.5 高级优化选项:     -ip/-ipo -prof-gen/-prof-use
2.6 其它常用选项:     -static -unroll(n) -recursive
方法二:尽可能使用最新版的Intel MKL数学库(10.3)
1. 由Intel资深工程师针对Intel硬件平台充分优化
2. 最大限度的避免了Cache Miss/Branch Miss Prediction等性能问题
3. 最大限度的使用了处理器内部的资源,比如SSE处理单元,64位扩展寄存器等
方法三:修改应用程序来辅助编译器优化程序
1. 通过Intel VTune Amplifier查看程序运行热点函数和热点代码段

呵呵,毕竟是以intel为主题的,不算是很通用的优化方法。

intel

向量

还在我刚工作的时候,我的一个头头就说希望能有一个像仪表盘的服务器监控系统,但是他也没有具体想法,因为如果一台机器就展示为一个仪表盘,那一百台,一千台当如何展示?如今陈健先生给了些启发,他强调:表盘也好,数字也好,都不如颜色给人的感觉直观,所以,干脆就让每一台机器都变成一个颜色块,颜色块里还分内存监控/CPU监控/硬盘监控等等,以不同颜色表示不同监控项,就比较直观了,虽然做不到一眼就看出每台机器的细节,但是一瞥之下找出运行不正常的机器还是很容易的。由于会场很暗,我只有一张不太清楚的照片:

监控

那些绿快快里面还有很多细节,鼠标移上去会自动放大。确是不错的想法。
前几次开发中,研究了一下硬盘的layout,看到ext2下的目录都是把自己的子文件的信息——更准确的说是ext2_dir_entry结构——放在自己的data block里(当然,可能是多个data block),存放顺序就是创建这些子文件的顺序。
前天李勇同学点拨,才知道从ext3开始,还多了一个"dir_index"特征(默认的),启用后,ext3_dir_entry(目录下的文件名信息)将以类似btree的形式存放在目录的data block里,其中用于排序的是子文件信息的hash值。
ext3, dir_index

如上图。目录inode的第一个data block(标注为index_block)里是由一堆dx_dentry结构组成的,这个data block还有个struct dx_root作为头部。
在我的实验里,一个目录里创建了1000个文件,且文件系统的block size是1024字节,此时目录的index_block里有22个dx_entry结构,这22个dx_entry是按照其第一个成员变量——hash来排序的,而第二个成员变量——block分别指向22个磁盘块,这些被指的磁盘块里才放着ext3_dir_entry结构。这个index_block就相当与btree里的索引节点,而被指向的磁盘块就相当于btree里的叶子节点

对于非dir_index的ext3文件系统,在目录里寻找某个文件名只能是顺序遍历,一旦文件数多了速度就会很慢;而在使用了dir_index后,就能迅速定位到在哪一个磁盘块了。可惜,在定位到某个磁盘块以后,只能是遍历这个磁盘块里的所有ext3_dir_entry了。


====== 2011.3.21 ======

1. 一个目录刚创建或目录里文件数很少的时候,并不采用dir_index(从inode的i_flags字段也可以看出这一点),当目录下的文件数越来越多,其ext2_dir_entry结构占用超过一个block后,才会将该目录变为dir_index
2. 即使是dir_index,一个目录下可放的文件数也不是无限的,从我们的实验来看,对于一个block size为4K的文件系统,如果用户的文件名很大(我们的实验是100个字节),一个目录下也就最多放500万个文件,超过这一限制,内核就会狂报"dir index full“的错误。因为dir_index在设计上就最多只允许两层索引节点加一层叶子节点。


====== 2011.5.19 ======

1. 不管在ext3还是在ext4,dir_index都只允许两层索引,也就是说,inode指向一个存满了dx_entry的block,其中某个dx_entry指向另一个存满了dx_entry的block,这第二层的dx_entry就只能指向一个存ext3_dir_entry的block,不能再指向一个存dx_entry的block ...... 但愿我说明白了。
2. 从coly同学那里新学到的:随着目录下文件的增加,这个dir_index的tree会保持平衡,但是如果删除目录下的文件,这个tree不会再作 rebalance 操作(也许是怕代码太复杂),tree有可能会慢慢变得“歪”起来。

tmux 滚屏

| | Comments (3) | TrackBacks (0)
我的tmux把Ctrl + a设为prefix,如果想滚屏,可以 Ctrl + a再按"[",此时进入所谓的copy-mode,然后就可以用上下键或PageDn/PageUp浏览屏幕了。想退出copy-mode直接按"q"。
我用惯了vi,对上下键不习惯,tmux号称是支持vi快捷键的,不过需要在.tmux.conf里加一行:
setw -g mode-keys vi
我试了一下,tmux-1.1是不支持这个配置项的,必须装 tmux-1.3或更高版本(另还需要libevent-1.4),才能顺利用vi按键方式滚屏。

今天用 Ctrl + a 加"?"看了tmux的所有快捷键,还支持分屏,这个我居然从来没用过,老土了。
重装rhel5后,忘记了root密码,于是想进入single user模式,文章 http://titanictom.blog.163.com/blog/static/1329184420105134027785/介绍的最清楚(还有截图),但是,我直接在kernel那一行后面加入“ single”,却无法成功。
反反复复试了几次,终于知道了:要删除 “console=tty0 console=ttyS1,57600“ 这些rhel5自带的启动项,直接在root=xxx后面跟上single,就像这样:

kernel /vmlinuz-2.6.18-238.el5 ro root=LABEL=/ single

便可以顺利进入single user mode,改root密码了。