Sunday, February 27, 2011

测试硬盘IO性能的工具

hdparm - get/set hard disk parameters
测量使用bufferedIO(默认)的throughput
$ sudo hdparm -t  /dev/sda1 
/dev/sda1:
 Timing buffered disk reads:  344 MB in  3.00 seconds = 114.55 MB/sec
测量使用directIO的throughput
$ sudo hdparm -t --direct /dev/sda1 
/dev/sda1:
 Timing O_DIRECT disk reads:  572 MB in  3.01 seconds = 190.08 MB/sec

iozone - benchmark filesystem
使用directio (-I), 一共1m个record (-s 1m), 每个record 大小为4kB (-r 4k), 分64个线程来读(-t 64), 使用POSIX pthread (-T). benchmark的类型由-i指定
0=write/rewrite,
1=read/re-read,
2=random-read/write,
3=Read-backwards,
4=Re-write-record,
5=stride-read,
6=fwrite/re-fwrite,
7=fread/Re-fread,
8=random_mix,
9=pwrite/Re-pwrite,
10=pread/Re-pread,
11=pwritev/Re-pwritev,
12=preadv/Re-preadv


/localfs$ iozone -I -s 1m -r 4k -i 0 -i 2 -t 64 -T
 Iozone: Performance Test of File I/O
         Version $Revision: 3.308 $
  Compiled for 64 bit mode.
  Build: linux 

 Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins
              Al Slater, Scott Rhine, Mike Wisner, Ken Goss
              Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR,
              Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner,
              Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy,
              Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root.

 Run began: Wed Apr 20 18:07:37 2011

 O_DIRECT feature enabled
 File size set to 1024 KB
 Record Size 4 KB
 Command line used: iozone -I -s 1m -r 4k -i 0 -i 2 -t 64 -T
 Output is in Kbytes/sec
 Time Resolution = 0.000001 seconds.
 Processor cache size set to 1024 Kbytes.
 Processor cache line size set to 32 bytes.
 File stride size set to 17 * record size.
 Throughput test with 64 threads
 Each thread writes a 1024 Kbyte file in 4 Kbyte records

 Children see throughput for 64 initial writers  =   69712.78 KB/sec
 Parent sees throughput for 64 initial writers  =   53411.80 KB/sec
 Min throughput per thread    =     929.10 KB/sec 
 Max throughput per thread    =    1169.92 KB/sec
 Avg throughput per thread    =    1089.26 KB/sec
 Min xfer      =     820.00 KB

 Children see throughput for 64 rewriters  =   68695.96 KB/sec
 Parent sees throughput for 64 rewriters  =   67008.63 KB/sec
 Min throughput per thread    =     844.21 KB/sec 
 Max throughput per thread    =    1173.81 KB/sec
 Avg throughput per thread    =    1073.37 KB/sec
 Min xfer      =     744.00 KB

 Children see throughput for 64 random readers  =   79020.74 KB/sec
 Parent sees throughput for 64 random readers  =   78204.49 KB/sec
 Min throughput per thread    =    1117.41 KB/sec 
 Max throughput per thread    =    1314.01 KB/sec
 Avg throughput per thread    =    1234.70 KB/sec
 Min xfer      =     872.00 KB

 Children see throughput for 64 random writers  =   44820.63 KB/sec
 Parent sees throughput for 64 random writers  =   38207.94 KB/sec
 Min throughput per thread    =     647.45 KB/sec 
 Max throughput per thread    =     748.67 KB/sec
 Avg throughput per thread    =     700.32 KB/sec
 Min xfer      =     888.00 KB



iozone test complete.

Sunday, February 06, 2011

zsh使用心得

抛弃了tcsh开始使用zsh了一段时间.zsh的特点是:fancy. 记录一下使用的心得
参考
https://wiki.archlinux.org/index.php/Zsh
http://zshwiki.org/home/
zsh workshop

使用
export var="value"


Completion System
官方介绍
发现cd补全的时候除了local-directories以外总是会出现users的选项, 很讨厌
去掉方法:"unsetopt cdablevars"

C++笔记

继承
继承方式:
  • public: 可以被任何人访问
  • protected:可以被本类以及子类访问
  • private: 只允许本类访问
虚继承: C++支持多重继承,也就是一个类可以同时有多个直接继承的基类.如果碰到如下的继承方式
A
| \ 
B  C
 \ |
   D
也就是类B和C分别继承A,同时D继承了B和C.这时候我们就需要使用以下的方法来让B和C虚继承A:
class A {
public:
    void printA() {}
};
class B:virtual public A;
class C:virtual public A;
class D:public B,public C;
如果B和C不使用虚继承,那么最终派生类D中就有可能含有两个A的作为基类,从而产生了二义性.


类型转换


C中的类型转换可以将一种类型的指针转换为任何其他类型的指针, 比如
ptr2 = (ClassFoo*) &obj;
C++中,可以有更多的选择
  • dynamic_cast <new_type> (expression) 可以将子类指针转化为父类指针
  • static_cast <new_type> (expression)可以将相关联的类指针互相转化, 比如子类指针到父类指针,或者父类指针到子类
  • reinterpret_cast <new_type> (expression)可以将任何类型指针相互转化
  • const_cast <new_type> (expression)保证转化后的指针是const


构造函数


派生类构造函数的调用顺序 如果基类的构造函数没有参数, 那么在进入派生类构造函数之前,基类构造函数将会被自动调用. 如果基类的构造函数有参数,那么派生类需要显式的调用基类构造函数.也就是所谓的"constructor chaining". 并且由于支持多继承,C++不能象Java那样使用super()
class Derived : public Base
{
    public:
        Derived(int foo, int bar)
        : Base(foo), bar_(bar)   // Call the superclass constructor in the subclass' initialization list.
        {
            // do something with bar
        }
};
explicit 关键字explicit可以修饰构造函数, 使得"converting constructor"非法.
class A {
public:
    A(int);
};
class B {
public:
    explicit B(int);
};
main() {
    A a1 = 37; // 合法
    A a2(37);  // 合法
    B b1 = 37; // 非法
    B b2(37);  // 合法
}


析构函数


virtual 有时候类的析构函数会被virtual关键字修饰, 这样可以强迫该类的派生类对象析构的时候使用派生类的析构函数而不是基类的----哪怕该对象是当做一个基类来被引用. 注意,一般说来当一个类含有虚方法的时候, 原则上就应该让析构函数为虚----因为虚方法意味着这个类多半是作为interface来使用.
class Base {
    virtual ~Base();
};
class Derived : public Base {
    ~Derived();
};
int main()
{
    Base* p = new Derived;
    delete p; // virtual destructor used to ensure that ~Derived is called
}


成员变量/函数


virtual 使用该关键字最主要的目的在于,当使用父类型的指针指向其子类的实例的时候,可以通过通过父类的指针调用实际子类的成员函. 编译器看到virtual关键字修饰的函数时,就会使用动态绑定(dynamic binding)在运行期决定函数的入口,而不是像普通的未被virtual关键字修饰的那种函数那样在编译期就静态绑定(static binding)函数入口.比如执行下面的代码
class Base {
    public:
        void foo() { cout << "Base::foo" << endl; }
        virtual void vfoo() { cout << "Base::vfoo" << endl; }
};
class Derived: public Base{
    public:
        void foo() { cout << "Derived::foo" << endl; }
        void vfoo() { cout << "Derived::vfoo" << endl; }

};
int main() {
    Base *p;
    p = (Base*) new Derived;
    p->foo();
    p->vfoo();
}
输出为
Base::foo
Derived::vfoo
static 静态成员变量是为了让同一种类的不同实例共享数据.该静态成员变量的初始化在类外,例如
int MyClass::MyStaticVar = 1;
静态成员函数与普通成员函数区别在于没有this指针,所以无法得知是针对哪个实例的操作.因此静态成员函数只能访问静态成员变量. 静态成员函数也不能被virtual, const, volatile, 以及const volatile所修饰. constconst修饰的成员函数无法是read-only, 不能修改任何调用者的成员.
class Test {
    public:
        int test;
        void foo() {test = 1;} // 合法
        void cfoo() const {  test = 1;} //非法
};
const不能修饰构造和析构函数,并且不能被非const函数重载.


inline inline函数在编译期被替换至caller的代码中,所以节省了函数调用的开销.在 C++当中,尽量用inline而不是#define.inline的成员函数定义必须在头文件中,

ref: http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.1


变量


const 用于声明那些编译期就可以确定值的变量,这样的编译器可以比用C中的#define替换要知道更多的信息,从而给出更给力的报错信息.用const声明的变量必须立即赋值--否则之后无法对该变量进行赋值或者修改.
int main() {
   const int i = 5;
   i = 10;   // 非法
   i++;   // 非法
}

ref http://duramecho.com/ComputerInformation/WhyHowCppConst.html
volatilevolatile关键字修饰一个变量是为了通知compiler不要对这个变量进行优化----因为这个变量可能被其他thread或者被系统使用.


模版(Template)


模版类的实现必须包括在.h文件中,否则编译的时候会找不到模版类的实现.
具体原因参见http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12
参数 Template可以使用class,typename参数,也可以使用非类型变量比如一个int或者char变量
template <class C, typename T, int N>
class myclass {
    T seq[N];
};
继承模版类
template <typename T>
class Base {
    T seq[N];
};
template <typename T>
class Derived: public Base< T > {
};

Tuesday, February 01, 2011

rubber

用法
rubber是一个latex的wrapper. 它免去了你先把eps -> pdf, 再latex paper.tex, 再bibtex paper 再 latex paper.tex这个复杂的过程. 你只需要一个命令就能完成
$rubber paper

问题/解决
不同的版本/平台上, rubber可能会有一些问题:
1 eps转pdf的时候报错
GS_OPTIONS=-dPDFSETTINGS=/prepress rubber --pdf -Wrefs -Wmisc paper
running: epstopdf --outfile=aaa.pdf aaa.eps...
Traceback (most recent call last):
  File "/usr/local/bin/rubber", line 4, in 
    sys.exit(Main()(sys.argv[1:]))
  File "/Library/Python/2.6/site-packages/rubber/cmdline.py", line 319, in __call__
    return self.main(cmdline)
  File "/Library/Python/2.6/site-packages/rubber/cmdline.py", line 283, in main
    ret = env.final.make(self.force)
  File "rubber/depend.py", line 157, in make
  File "rubber/depend.py", line 171, in make
  File "rubber/depend.py", line 276, in run
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 595, in __init__
    errread, errwrite)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 1106, in _execute_child
    raise child_exception
OSError: [Errno 8] Exec format error
make: *** [pdf] Error 1

修改/usr/local/share/rubber/rules.ini
command = epstopdf --outfile=$target $source
改为
command = bash epstopdf --outfile=$target $source

2 无法使用bibtex
在我的Mac上, bibtex后面不能使用绝对路径(Ubuntu上则是好的, 很诡异).所以导致我rubber以后所有reference都不对.