Recently in 软件开发 Category

前一阵子买了一块Cubieboard,就是类似RaspberryPi的ARM板子,之所以选Cubieboard而不是RaspberryPi是因为Cubie的配置更高——1Ghz的ARM核(全志A10),1G的DDR内存,4G的NAND,还带一个SATA口(做为一个靠廉价存储混饭吃的loser,我热爱SATA口)。

板子拿到手,跟照片一模一样,Tom Cubie(Cubieboard的设计者)同学不欺我也。可回收的纸盒子也很可爱。

cubieboard

开始是用wiki上提供的Buildroot方法把编译好的image烧到板子上的NAND里,可以成功启动到Linux 3.4.5 kernel,字符终端,可以联网,但是毕竟系统工具都是用busybox攒的,太少,不够方便,也没有包管理工具。此root系统带有一个CedarXPlayer工具,可以看1080p的视频,即使是高清的rmvb都很流畅(这小板子确实厉害),但是,这个神奇的CedarXPlayer工具不支持快进快退甚至连暂停都不支持,而且退出播放时需要用Ctrl + c,纯属测试工具。

cubieboard

所以,还是改用SD卡启动,论坛上有人提供了BerryBoot,用它可以直接把linaro(可以理解为ARM版的ubuntu)装到SD卡上,能成功进到图形界面,只是分辨率有点低。但此时我再用vlc看rmvb的时候就变得特别卡了,想来是跟显卡驱动有关系,于是按论坛上的说法装了显卡驱动,但还是不好使,只好发邮件问Tom Cubie,他非常耐心的回答了我:

        CedaX 是Allwinner自己的一个框架,http://linux-sunxi.org/CedarX
        Linux下媒体播放你可以看看这个
        http://linux-sunxi.org/VLC

我按照文档里的步骤装了VLC,居然不出图像。嗯,我还需要好好琢磨琢磨。

Cubieboard不光是能做高清播放机,那个sata口加上板子上的 2 pin 的电源口,完全可以接一个2.5寸的笔记本硬盘(或者有钱的话,一个SSD)。想想看,一个5V电压2A电流的ipad充电器,就可以带动一个基于ARM的NAS(Cubieboard加一块2.5寸硬盘),才10瓦功耗的NAS呀,放在家里,可以下个BT,做个共享,看个电影,还是很有优势的。

同事何燕峰送了我一个小机箱,我便把Cubieboard和一个3.5寸的硬盘(实在找不到2.5寸的,3.5寸的硬盘光靠Cubieboard上的2 pin电源口是带不动的,要另外供电,因为2.5寸硬盘只需要5V的电压,而3.5寸硬盘需要12V和5V两种电压)一起放进机箱里,还挺合身:
cubieboard

猜猜Cubieboard的设计者Tom Cubie同学多大?2010年的本科毕业生。人家都有自己的事业了。想想我自己,三十好几的人了,还在给人修bug、做测试、调性能,还不招人待见,真是惭愧。

我以后要多向Tom Cubie同学学习。

代码review

| | Comments (1) | TrackBacks (0)
我:我们有两台机,都是一样的 xeon E5620 2.4G 的CPU,但是,跑算Pi的程序,5000个迭代,一个机器跑48秒,另一个只需要32秒

coly:CPU核数一样吗?

我:一样的。不一样应该没关系,我这是单进程。

coly:内存速度不一样?

我:就一个算Pi,总共就占8MB内存,还没有CPU的L3 cache大呢

coly:要不这样,你写个死循环加法,我们看看两边的速度是不是一样

(公司的盒饭送来了,晚饭时间)

coly:你先吃,我来写吧....一个死循环我应该还是能写出来的....你要review我的代码哟~
我:....

(coly把代码写出来了

int main(void)
{
        int a=0;
        while ( a < 0) {
                a++;
        }


        return 0;
}


coly:为什么我运行瞬间就结束了?
我:应该是编译器把你的死循环优化掉了,因为a这个变量在整个main函数里都没有被其它地方使用
coly: 喔~~,我改改,在结尾加个printf把a打出来

(程序一运行还是瞬间结束)
陈同学:(看了看代码)是不是加法太快了,看不出来?咱们加几个嵌套循环
coly:好~

(程序还是瞬间结束)

coly:怪了....靠,a的值是0啊,根本进不了循环!
我,陈同学齐声:喔~~~

coly:你们两个!怎么review代码的!




后记:

死循环程序写出来了,两台机器CPU的计算速度确实有差异,原因最后由柯旻同学揭示:

跟华为2285机器的cpu 频率控制有关
CPU不开启cpuspeed就是1.6G的主频,需要

/sbin/modprobe acpi-cpufreq
echo ondemand |sudo tee /sys/devices/system/cpu/cpu13/cpufreq/scaling_governor

后,主频才上到真正的2.4G
这一阵子的工作是在给ext4加feature,就是“让ext4的extent length的单位由block变为cluster“。一边写代码一边加测试用例,这个测试用例我就简单的用shell实现的,就用dd命令来写文件。

顺序写的时候还好,等到偏移写(seek一段再write)的时候出了kernel crash,原因是某个extent的length突然变成了0。一开始当然是怀疑我自己哪里写错了,于是加断点,调试,直到我去南京出差周末在宾馆也在调试(感谢马涛同学提供的虚拟机镜像,不然连不上vpn就没法调了),发现事情很神奇:我的extent开始length是2,dd之后还没干别的呢,length就变了,于是终于给dd加了个strace,一看,我的天,dd自己会做ftruncate!而我还没有实现truncate的新feature

这dd真是体贴得我流泪啊,我一直把它当纯write使啊,没想到dd会“智能“的多加一个truncate操作。去翻了一下dd的代码,只要是 of= 一个文件,dd必然会先truncate之,除非带上conv=notrunc。

看来工具不熟就是误事啊。

附dd用法(seek 8k然后write 8k,不要truncate):

dd if=/dev/zero of=/test seek=2 bs=4K count=2 conv=notrunc 
这几天用shell编程做一个简单的自动回归测试,需要用到shell的函数功能,大约是这样:


sum ()
{
    return `expr $1 + $2`
}

sum 3 4
echo $?        #result


一直用的不错,直到今天加了一个case,echo出来的返回值($?)就不对了,set -x调了一番,加法没错,但echo出来就是不对,最后暴力改改,让返回值变为直接 return 1024,咦?echo的东西变了,于是一番google,找到了这篇

原来shell里面函数的返回值是用的errno,而errno只支持0-255,所以如果返回值太大就返回的不对了。

替代方案是干脆用“全局变量”


RES=0

sum ()
{
RES=`expr $1 + $2`
}

sum 133 244
echo $RES
sum 333 444
echo $RES

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监控/硬盘监控等等,以不同颜色表示不同监控项,就比较直观了,虽然做不到一眼就看出每台机器的细节,但是一瞥之下找出运行不正常的机器还是很容易的。由于会场很暗,我只有一张不太清楚的照片:

监控

那些绿快快里面还有很多细节,鼠标移上去会自动放大。确是不错的想法。

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的所有快捷键,还支持分屏,这个我居然从来没用过,老土了。