博文

目前显示的是 七月, 2012的博文

Intel AES NI性能测试

老大派我去找找看有没有什么便宜好用的AES硬件加速卡,于是我就想先试一试Intel CPU自身的硬件加速功能。 我的测试环境是CentOS release 5.7 (Final),所用的CPU是Intel(R) Xeon(R) CPU X5675 @ 3.07GHz。不得不说,这么好的一个CPU配这么老的一个操作系统真是可惜了。 首先,拿系统自带的openssl作测试, $ openssl speed -evp aes-128-cbc
Doing aes-128-cbc for 3s on 16 size blocks: 16189439 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 64 size blocks: 4972096 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 256 size blocks: 1280673 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 1024 size blocks: 321781 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 8192 size blocks: 40365 aes-128-cbc's in 3.00s
OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008
built on: Sat Aug 13 18:21:50 EDT 2011
options:bn(64,64) md2(int) rc4(ptr,int) des(idx,cisc,16,int) aes(partial) blowfish(ptr2)
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -I/usr/kerberos/include -DL_ENDIAN -DTERMIO -Wall -DMD32_REG_T=int -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOUR…

我对开源的看法

有这么一种观点:程序员要想提高技术水平,多读开源代码、多参与社区讨论与开发就好了。我以前很赞同,现在发现不是这样。panpan和xuhui对我的批评是,多看看技术以外的东西。我的理解是这样,很多东西它之所以这么做,不是因为技术上是最优的,而是因为工期、领导的旨意、需求变更留下的历史问题等等。这些原因是无法通过阅读代码而得知的,我只能看到实现细节,却不能知道作者的设计意图。像Qt、leveldb这样的项目,名为开源,但是它并没有采用开放式的开发。只是这个公司将其技术成果共享出来了而已,中间的过程完全不可得知。举个例子,Nokia和Intel说要合伙做一个叫Meego的操作系统。Intel说好啊,我对Linux熟,我来优化底层系统,Nokia你来搞QT及上层软件。结果Intel很郁闷的发现,Nokia的Meego项目组有两套BUG管理系统,一套是对内的,只有Nokia自己的员工可以访问(intel的不行),一套是对外的,放在社区里让任何人都可以去提BUG。然后Intel就怒了,你这让我们怎么合作?Nokia也很委屈,因为对任何一个手机厂商来说,未上市的手机的硬件细节是很重要的商业机密,这些东西很容易通过BUG管理系统中的日志文件和coredump流露出来。所以,大多数软件厂商最终选择的都是Nokia这样的做法。很多时候要想清楚自己的目的,是让项目尽快完工,还是追求纯技术?如果是后者,不如老老实实在学校或者研究所呆着。做项目最重要的不是解决一个多么大的技术问题,而是尽可能的把所有技术困难都绕开,然后再解决那些不得不解决的。这时便会引申出一个重要原则:Simple is the best。读代码跟读小说不一样。写小说的人心里一定是有读者在的。所以每拿起一本古典小说的时候,就仿佛穿越了时空在跟一个已经死去的人对话。而代码不一样,代码主要还是给机器读的,以及给自己读。举个例子,如果你对C++的模板推导很擅长,你会因为这门技术太晦涩,有人有可能看不懂,而不用吗?所以如果想通过代码猜透作者的设计企图,不管能不能做到,总之为其花费的代价实在是太高。那么有别的方法吗? 有啊! 跳到这个公司去,中午跟作者一起吃个饭,随便套两句,就出来了。对我自己来说,很有幸能在一流的互联网公司工作。如果我想去百度、腾迅、阿里中的任何一家,应该都是有机会的。所以,总有比我资深的老员工,如果有幸遇到一个比…

线性同余发生器的参数如何选取?

我们平时所用的伪随机数生成器(PRNGs)主要有两种:线性同余发生器(Linear Congruence Generator)和反馈位移寄存器法(Feedback Shift Register)。LCG线性同余发生器是通过这样的递推函数产生随机序列:x=(a*x+c)%M (x,a,c,M都是非负整数)这样产生的随机数序列,一定是有周期的,且小于等于M。在实际应用中,当然希望周期越大越好。我在我的笔记本电脑上测试,生成20亿个随机数只需要20秒左右。如果遇上需要大量随机数的程序,很快就会将这个生成器的"随机性"耗尽。如果以下三个条件都满足,则可以让该随机数序列的周期等于Mc和M互质。 对于M的任何一个质因子P,a-1能被P整除。 如果4是M的因子,则a除以4余1。(这个定理的证明非常复杂,请参考数论的书)在计算机系统中,M通常选择是2的整数倍,如\( 2^{48} \),\( 2^{32} \)。M通常由计算机的字长所限,于是在M给定的情况下,如何选择a和c,则很关键。可以证明,如果M是2的整数次幂,如果a和c满足以下条件,则该序列的周期等于Ma除以4余1。 c除以2余1。(这个证明过程非常显然,请自推一下)下面假设通过x=(a*x+c)%M得到的数列为\( \{X_n\} \),那么我们希望它满足[0,M-1]之间的等可能分布。那么它的概率密度函数为:$$ \begin{equation} \rm P(X_n = i ) = \left\{ \begin{array}{ll} \frac{1}{M}, & i=0,1,\dots,M-1 \\ 0, & other \end{array} \right. \end{equation} $$于是它的数学期望应该为:$$ E(X_n) = \sum_{i=0}^{M-1}iP\{X_n=i\} = \frac{M-1}{2} $$方差应该为:$$ Var(X_n) = E(X_n^2)-(E(X_n))^2 = \frac{1}{M}\sum _{i=0}^{M-1} \left( i- \frac{M-1}{2} \right) ^{2} = \frac{M^2}{12}-\frac{1}{12}$$下面计算\( X_n \)的1阶自相关系数,$$ \rho = \frac…

NAT连通性测试工具以及Flash P2P中的NAT穿透原理

图片
由于公网IP有限,NAT几乎是无处不在。比如我们在家里,牵一个ADSL,用Modem拨号得到一个公网IP,然后在Modem后面再接一个路由使得多个设备能同时上网。路由会有一个公网IP一个私网IP,然后家里的其它设备都用的是私网IP。此时路有器就要完成一个很重要的职责:对于进出它的包做网络地址转换。NAT是在传输层及以上做的,传输层最主要的2个协议是TCP和UDP,下面只考虑UDP。对于UDP而言,每个包都有很基本的4个要素:src ip、src port、dst ip、dst port。根据在做NAT的时候是否保留src ip和src port,可以把NAT分为这么三种:Cone: 将src ip映射到一个固定的IP,并且将src port映射到一个固定的Port,无论dst ip和dst port是什么。假如我从192.168.0.2:5000,通过路由器发一个UDP包给66.66.88.88:4000端口,而路由器把这个包的src ip和src port翻译成了173.245.73.182:5000。那么在此后一段时间内,无论我从192.168.0.2:5000往外面的任意IP、任意端口发包,src ip、src port都会被翻译成173.245.73.182:5000。Single IP address, symmetric:将src ip映射到一个固定的IP,将src port映射到一个随机的port,但是保证对于相同的(dst ip,dst port), src port始终相同。(否则双方没法通话啊,回来的包回给哪个端口呢?)举例:假如我从192.168.0.2:5000,通过路由器发一个UDP包给66.66.88.88:4000端口,而路由器把这个包的src ip和src port翻译成了173.245.73.182:5000。那么在此后一段时间内,无论我从192.168.0.2:5000往外面的任意IP、任意端口发包,src ip都会被翻译成173.245.73.182,但是src port嘛,可就说不准了。Multiple IP address, symmetric:与上面类似,但是src ip可能会被映射到多个IP中的一个。最典型的就是假如你的网关做了双线接入,那么你访问电信的资源就会走电信的那个IP出去,你访问网通的资源就会走网通的IP出去…