2008年3月21日星期五

Ubuntu穿墙

和Windows相比,在Ubuntu下穿墙太简单了。

首先安装众所周知的两个服务:
sudo apt-get install tor privoxy

然后打开9050端口,供firefox使用
在配置文件 /etc/privoxy/config 中,取消注释掉
forward-socks4a / 127.0.0.1:9050 .
一行即可打开
修改完配置文件重启privoxy:
sudo /etc/init.d/privoxy restart

最后安装firefox插件torbutton
需要穿墙的时候点一下即可
click to enable/disable tor

根据tor穿墙原理,用tor是安全的,也就是不用担心含密码的数据包在转发途中被看到明文,因为所有数据包在tor系统中都加密了。也正因为如此,tor比较慢。

2008年3月10日星期一

Bezout Equation

今晚做了一个小练习,用欧几里得算法计算两个正整数的最大公约数。同时计算出Bezout等式的系数。递归描述更紧凑,突出欧几里得算法的核心内容,迭代描述算系数比较方便。
#include<stdio.h>
int gcd(a, b)
{
    if (a>=b)
        if (b>0)
            return gcd(b, a%b);
        else
            return a;
    else
        return gcd(b, a);
}

int gcdp(int x, int y, int* a, int* b) {
    int r=0, k=0, i=1;
    int ai=0, aii=0, bi=0, bii=0;
    int t=0, reverted=0;
    if (y>x) {
        t=x;
        x=y;
        y=t;
        reverted=1;
    }
    while (1) {
        r=x%y;
        k=x/y;
        if (r==0) {
            if (i==1)
                *b=1;
            if (reverted) {
                t=*a;
                *a=*b;
                *b=t;
            }
            return y;
        }
        x=y;
        y=r;
        switch (i) {
        case 1:
            *a=1;
            *b=-k;
            break;
        case 2:
            ai=*a;
            bi=*b;
            *a=-k;
            *b=1-bi*k;
            break;
        default:
            aii=ai;
            bii=bi;
            ai=*a;
            bi=*b;
            *a=aii-k*ai;
            *b=bii-k*bi;
            break;
        }
        i++;
    }
}

void test(x, y)
{
    int a=0, b=0;
    int r=gcdp(x, y, &a, &b);
    printf("%d * %d + %d * %d = %d\n", a, x, b, y, r);
    if (a*x+b*y!= r)
        printf("Error %d = %d\n", a*x+b*y, r);
}
int main() {
    test(12, 34);
    test(1, 2);
    test(4, 6);
    test(32465, 18078);
    test(36465, 18278);
    return 0;
}

没有考虑负数和零的情况。

2008年3月6日星期四

No Generic in C++?

一直以为Java的泛型是从C++的模板学来的,所以C++的模板也应该能够很好的支持最简单的泛型编程。
今天尝试写一个小Demo的时候发现,C++竟然不支持把模板类的声明和实现分到两个文件!
主程序中
Faint::Heart *h=new Faint::Heart();
h->test<int>(-1);
声明Heart.h
#ifndef HEART_H_
#define HEART_H_

namespace Faint {
class Heart {
public:
Heart();
virtual ~Heart();
template<class T> T test(T t);

};

}

2008年3月5日星期三

Hello MPI

并行计算这门课有一个实验平台,用MPI搭建的。课程还没有讲到,我已经迫不及待地想尝试一下了。虽然我既不会C也不会MPI,但是找本书来弄个Hello
World还是可以的――

首先,登录到实验平台的Linux操作系统上。例如
ssh wangyuantao@166.111.XXX.XXX
按照提示输入密码

然后到自己的目录中创建一个hi.c文件,内容如下:

#include "mpi.h"
#include <stdio.h>
void main(argc, argv)
int argc;
char *argv[];
{
int myid, numprocs;
int namelen;
char p_name[MPI_MAX_PROCESSOR_NAME];

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Get_processor_name(p_name,&namelen);
fprintf(stderr, "Hello MPI, Process %d of %d on %s\n", myid,
numprocs, p_name);

MPI_Finalize();
}

用途是打印进程号、组大小和节点名称。这个hello小程序没有进程间交互。

这个平台上有两个计算节点,node1和node2。在运行MPI时需要指定节点配置文件hosts,这个文件只有两行:
node1-ib
node2-ib
由于这个网络用infiniBand连接,所以多了-ib这个后缀。

这时就可以登录到计算节点上去编译了。
ssh node1
然后找到对应目录(这个实验平台中,计算节点的home路径被mount到了166.111.XXX.XX的home路径)
编译:
mpicc hi.c -o hi
得到可执行文件hi

最后启动运行就可以了
mpirun -machinefile hosts -np 6 hi
其中-machinefile指定了计算节点列表,任务被按照默认的方式负载均衡到各个计算节点。
-np指定了开启几个进程,也就是并行的度。

运行结果都在命令行上打印出来了
Hello MPI, Process 0 of 6 on node1-ib.test
Hello MPI, Process 2 of 6 on node1-ib.test
Hello MPI, Process 4 of 6 on node1-ib.test
Hello MPI, Process 1 of 6 on node2-ib.test
Hello MPI, Process 3 of 6 on node2-ib.test
Hello MPI, Process 5 of 6 on node2-ib.test


P.S.
如果在本机上编辑源代码,然后上传到服务器上,可以用scp命令
scp hi.c wangyuantao@166.111.XXX.XXX:2007211XXX/helloworld/
然后按照提示提供密码,文件就传上去了。

如果不相信程序真的是在两个计算节点执行的,可以打印时间戳,一般计算节点的物理时钟很难精确同步的,也没必要,逻辑时钟正确就行了。
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
fprintf(stdout, "Hello MPI, Process %d of %d on %s @ %s\n",
myid, numprocs, p_name, asctime(timeinfo));
输出结果:
Hello MPI, Process 0 of 3 on node1-ib.test @ Wed Mar 5 16:33:02 2008
Hello MPI, Process 1 of 3 on node2-ib.test @ Wed Mar 5 16:34:38 2008
Hello MPI, Process 2 of 3 on node1-ib.test @ Wed Mar 5 16:33:02 2008

发现node2的时钟比node1的时钟快了一分多钟,呵呵~