星期六, 四月 30, 2011

LINUX下方便的代理工具 proxychains

这个工具很好 UBUNTU源里就有
装好后 修改文件 /etc/proxychains.conf 在[ProxyList] 后面写上你用的代理 比如
socks5 127.0.0.1 端口
然后 在想用代理的程序前加 proxychains
比如:
proxychains git pull

星期四, 四月 28, 2011

What every programmer should know about memory 阅读笔记(6.2.4)

http://lwn.net/Articles/255364/
6.2.4 Optimizing TLB Usage

有两种优化tlb的方法
第一 减少程序页数量的使用 这能减少tlb miss
第二 减少必须分配的页目录 提高目录搜索的cache命中率 这依赖于程序使用的虚拟地址
可采取的办法是关闭Address Space Layout Randomization (ASLR)
这个选项为了安全会让程序地址随机分配(gdb调试程序的时候为了帮助复现bug就关闭这个功能)
还有一种方法是mmap的MAP_FIXED选项来分配内存 其可让程序自己设置要分配出内存的地址 但是不推荐使用

What every programmer should know about memory 阅读笔记(6.2.3)

http://lwn.net/Articles/255364/
6.2.3 Optimizing Level 2 and Higher Cache Access

前面章节介绍过的对l1的优化方法也对l2或更高级的cache有效
但是要注意这些cache会和每个core或者硬线程共享 所以对性能的影响的大小会比实际cache的容量要小
l1 cache line的大小通常各平台差不多 即使不同也可以最大的为准 影响比较小 但是更高级别的cache在各平台差异很大 需要程序动态处理
取得cache结构在Linux下可在 /sys/devices/system/cpu/cpu*/cache 中取得相关信息

星期一, 四月 18, 2011

What every programmer should know about memory 阅读笔记(6.2.2)

http://lwn.net/Articles/255364/
6.2.2 Optimizing Level 1 Instruction Cache Access

尽量减小代码大小,要注意loop unrolling和inlining对代码规模的影响,保持平衡。
比如如果一个函数只调用一次,将其inline就没问题。

代码尽量是线性的,减少代码空洞(不需要经常执行的代码块)的存在。
比如一个条件执行代码 条件执行的并不会经常执行 这就会形成空洞。Linux
Kernel中使用了宏likely和unlikely,当使用这2个宏的时候,如果gcc编译选项 -freorder-blocks
(默认包含在-O2中 不包含在-Os中)打开,gcc就会将标记好的代码块移动到函数尾部,从而不产生代码空洞。
还有另一选项 -freorder-blocks-and-partition 但是有使用限制,其不能和exception handling 一起使用。

Intel Core 2有一种针对小循环的功能 Loop Stream Detector (LSD)。
如果一个循环has no more than 18 instructions (none of which is a call to a
subroutine), requires only up to 4 decoder fetches of 16 bytes, has at
most 4 branch instructions, and is executed more than 64
times。这个循环就会被锁进指令队列中,下次再执行这个循环速度就会更快。
一个大循环中的小循环,即使没有这个功能,执行速度也会快一些。

代码尽量对齐。对各种对齐问题,汇编器提供了.align伪指令来处理这种问题。
函数头的对齐。gcc 编译选项-falign-functions=N,函数都将以N对齐。如果一个小函数碰到一个很大的N,这就会造成浪费,对一个很少执行的函数,这也是浪费。后一种情况经常发生在库中,一个库会包行常用的函数和不常用的函数。一个正确的N的选择可以提高程序的效率。-fno-align-functions可以关闭这个选项。
基本块的对齐。gcc编译选项-falign-jumps=N,和上面的参数有同样的问题。
循环的对齐。gcc编译选项-falign-loops=N,和上面的参数有同样的问题。
最后还有一个参数-falign-labels,会影响程序速度,作者建议不要使用。

What every programmer should know about memory 阅读笔记(6.2.1)

http://lwn.net/Articles/255364/
6.2.1 Optimizing Level 1 Data Cache Access

大块读写时尽量将非顺序读写转化成顺序读写
而每次内存操作可以集中于一cache line,从而提高速度
取得当前系统cache line长度的命令为 getconf LEVEL1_DCACHE_LINESIZE
这样在编译当前系统执行的程序的时候 可以用 gcc -DCLS=$(getconf LEVEL1_DCACHE_LINESIZE)
将cache line长度传递到程序中
当然大块数据读写还是SIMD指令速度最快
上面提速的原理是提高cache 被污染前的再次使用机率

pahole program (see[dwarves])能显示一个struct 在cache 中的分布 文中建议可根据需要压缩struct
尽量让数据在同一cache line 同时按照访问顺序设置元素顺序 适当时可将一个struct 分成多个
需要时候可用posix_memalign分配cache line 对齐的内存
struct strtype {
...members...
} __attribute((aligned(64)));
标记内存对齐到多少

当使用variable length arrays (VLAs) 或者 alloca
的时候,为了保证frame的对齐,会增加很多相关代码,影响程序速度。这个我自己写了些代码看了下,确实增加了很多代码,如果是调用次数很多的函数,建议还是去掉vlas和alloca。

gcc支持一个frame对齐参数:
-mpreferred-stack-boundary=2
使用这个参数的时候,frame将以2的n次方对齐。所以上面让gcc生成的代码从默认的16字节切换为4字节。
作者认为在编译x86程序的时候设置这个参数为2,可以减少stack的使用并提高代码执行速度。(我没有测试过)
其他ARCH都不能设置为2,即使是x86_64。

星期五, 四月 15, 2011

What every programmer should know about memory 阅读笔记(6.1)

http://lwn.net/Articles/255364/

6.1 Bypassing the Cache

在写连续大块内存的时候 最好能绕过cache防止污染很多cache
gcc提供了一些函数可以绕过cache写内存但是文中实测效果不佳 连续读写只能达到同级水平 而随机读写更差

个人觉得还是以调用系统提供的memset等内存函数来操作内存 有些会使用更快速SIMD 指令 而且移植性更好