星期日, 十月 30, 2011

月初拍得小花

20111003,花

星期一, 九月 19, 2011

Ububtu 11.04 GNOME比较卡的解决 (metacity内存泄露修复方法)

最近装了Ubuntu 11.04 amd64版本 发现GNOME用起来很卡 用系统监视器 发现 metacity 竟然占了接近1G的内存
重启用了一上午 metacity 又占到了400M 看来是个内存泄露问题
而metacity 作为GNOME的关键组件 杀掉其或者卸载都是不成的 所以我介绍一下修复方法

基本思路就是 用11.10上的 metacity

首先建议11.04的用户用系统监视器看下自己机器上的 metacity 占了多少内存 如果比较大 应该是有泄露的

如果是AMD64系统:
wget http://mirrors.sohu.com/ubuntu/pool/main/m/metacity/metacity_2.34.1-1ubuntu4_amd64.deb
wget http://mirrors.sohu.com/ubuntu/pool/main/m/metacity/metacity-common_2.34.1-1ubuntu4_all.deb
wget http://mirrors.sohu.com/ubuntu/pool/main/m/metacity/libmetacity-private0_2.34.1-1ubuntu4_amd64.deb
sudo dpkg -i metacity_2.34.1-1ubuntu4_amd64.deb
metacity-common_2.34.1-1ubuntu4_all.deb
libmetacity-private0_2.34.1-1ubuntu4_amd64.deb
然后重启(新装的metacity 需要重启生效)

如果是i386系统(没有实际检查过是否有内存泄露问题):
wget http://mirrors.sohu.com/ubuntu/pool/main/m/metacity/metacity_2.34.1-1ubuntu4_i386.deb
wget http://mirrors.sohu.com/ubuntu/pool/main/m/metacity/metacity-common_2.34.1-1ubuntu4_all.deb
wget http://mirrors.sohu.com/ubuntu/pool/main/m/metacity/libmetacity-private0_2.34.1-1ubuntu4_i386.deb
sudo dpkg -i metacity_2.34.1-1ubuntu4_i386.deb
metacity-common_2.34.1-1ubuntu4_all.deb
libmetacity-private0_2.34.1-1ubuntu4_i386.deb
然后重启(新装的metacity 需要重启生效)

星期日, 七月 10, 2011

玩摄影的人你伤不起啊

早上带孩子去紫竹院呼吸新鲜空气 发现坐船看荷花挺方便 于是上了船

_MG_8497
发现一堆人拿着长枪短炮的对着一小片荷花狂拍

_MG_8503
船近了发现人可真是不少


_MG_8504


_MG_8530
面对这么一小片荷花和这么一大堆人 我评价一句 玩摄影的人真是伤不起啊

星期六, 六月 04, 2011

从launchpad PPA取得最新版本GDB

GDB和UBUNTU用户们你们好,

也许你还在用7.2或者更老版本的GDB,这里面BUG成堆压根没人管了,或者很好用的GDB新功能你也用不上.
或者你要同时在好几个体系结构上工作例如ARM和MIPS,而你要针对每个体系结构编译一个GDB.

我开始在launchpad PPA上发布UBUNTU 10.04, 10.10, 11.04,
11.10(8.04还有点问题)可用的最新版本的GDB(7.3 和 7.3.5).
这些GDB的特点是:
1. GDB maintainer天天更新他们,他们有最新的功能和更快的BUG修复速度.
2. 他们都用"--enable-targets=all
--enable-64-bit-bfd"选项编译,所以他们支持GDB支持的所有体系结构,你可以本地调试也可以随时用他们调试远程的其他体系结构的程序.
3. 包名是"gdb-7.3" 和 "gdb-trunk"而 GDB程序的名称是"gdb-7.3"和 "gdb-7.3.5".
所以其不会影响你原来安装的GDB, 如果你在使用新版GDB的时候出现问题,随时可以换回老版本的GDB.

取得他们请访问下面的URL:
https://launchpad.net/~teawater/+archive/gdb-10.04
https://launchpad.net/~teawater/+archive/gdb-10.10
https://launchpad.net/~teawater/+archive/gdb-11.04
https://launchpad.net/~teawater/+archive/gdb-11.10

谢谢,
teawater

星期一, 五月 16, 2011

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

http://lwn.net/Articles/256433/

6.4 Multi-Thread Optimizations
三个方面比较重要 一致性 原子性 带宽


6.4.1 Concurrency Optimizations
为了保持cache一致性 不同芯片的多线程写同一地址会效率差 单个芯片多core因为cache共享就会好很多

优化一致性的问题的核心思路是将一致性要求不同的变量放入不同的cache line

优化方法
方法一 读写变量和初始化后只读变量分入不同section(gcc对const变量会自动这么做) 使他们在内存和cache上分开 如果可以
还建议将读多写少变量分入单独section

方法二 将经常被同时访问的变量放入同一structure确保他们在内存结构上在一起

方法三 将经常被不同线程写的变量放入同一structure确保他们在内存结构上在一起

方法二 方法三可配合__attribute__((aligned(l1 cache line size)))确保全部变量在一个cache line

方法四 如果一个变量被多个线程分别使用 并且无一致性需求 可用__thread将变量放入tls


6.4.2 Atomicity Optimizations
主要介绍原子内存操作


6.4.3 Bandwidth Considerations
每个芯片连接内存都有一个最大带宽 而其会被芯片中的core和硬线程共享
多个芯片连接内存的方式可能也是共享的
所以效率也受到带宽的影响

比较新机器的performance measurement counters可以探测这个问题

方法一 买更快的机器 在带宽问题只能在部分机器出现 且换新机器比重写问题程序便宜的时候 这是个可用的方法

方法二 如果几个线程经常访问同样的数据 将同一进程的几个线程放在有cache共享的几个core上

方法三 如果几个线程经常访问不同的数据 不要将他们放入同一个core(我认为cache共享的几个core上) 否则易引起cache冲突

文中介绍了一些控制线程在哪个core上运行的接口

方法二 方法三是有冲突的 所以使用时务必分析好当前面对的问题 并作实验

星期三, 五月 11, 2011

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

http://lwn.net/Articles/256433/
6.4 Multi-Thread Optimizations
三个方面比较重要 一致性 原子性 带宽

6.4.1 Concurrency Optimizations
为了保持cache一致性 不同芯片的多线程写同一地址会效率差 单个芯片多core因为cache共享就会好很多

优化一致性的问题的核心思路是将一致性要求不同的变量放入不同的cache line

优化方法
方法一 读写变量和初始化后只读变量分入不同section(gcc对const变量会自动这么做) 使他们在内存和cache上分开 如果可以
还建议将读多写少变量分入单独section

方法二 将经常被同时访问的变量放入同一structure确保他们在内存结构上在一起

方法三 将经常被不同线程写的变量放入同一structure确保他们在内存结构上在一起

注意:方法二 方法三可配合__attribute__((aligned(l1 cache line size)))强制其和l1 cache
line对齐确保全部变量在一个cache line

方法四 如果一个变量被多个线程分别使用 并且无一致性需求 可用__thread将变量放入tls

星期四, 五月 05, 2011

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

http://lwn.net/Articles/255364/
6.3 Prefetching
6.3.1 Hardware Prefetching
两次或者更多次的cache miss才会引起prefetch 因为CPU有随机访问引起cache miss的情况 比如访问一个全局变量
如果这样也prefetch会影响效率
一个CPU中会有多个prefetch unit进行prefetch 高级的cache的unit可能多个core共享
prefetch不能越过一个页 因为可能引起page fault或者fetch一个并不需要的页
在不需要的时候引起prefetch 需要调整程序结构才能解决 在指令中插入未定义指令是一种解决方法
体系结构提供全部或者部分关闭prefetch


6.3.2 Software Prefetching
#include <xmmintrin.h>
enum _mm_hint
{
_MM_HINT_T0 = 3,
_MM_HINT_T1 = 2,
_MM_HINT_T2 = 1,
_MM_HINT_NTA = 0
};
void _mm_prefetch(void *p, enum _mm_hint h);
x86系列可用上面函数生成prefetch指令
_MM_HINT_T0 = 3, _MM_HINT_T1 = 2, _MM_HINT_T2 = 1, 就是将内存取到1 2 3级cache
要注意第一每个芯片可能对其实现不同 第二 一般使用MM_HINT_T0 但是如果数据量较大可用另两个选项
_MM_HINT_NTA的NTA是non-temporal access(原文在这里写错了)的缩写 当使用这个选项的时候 数据将被装入l1
但是当这个cache要装入其他数据的时候 原来的数据将不会被存入更高级别的cache 如果有需要数据还要直接写入内存
注意如果数据量很大不要使用这个选项
AMD的CPU提供一种特殊的prefetch指令
直接在程序中增加prefetch代码可能起到作用不大 建议方法是用performance counters查询程序的cache
misses信息 在需要的位置插入prefetch指令
-fprefetch-loop-arrays是GCC提供的编译选项 其将为优化数组循环插入prefetch指令 但是这个选项要小心使用


6.3.3 Special Kind of Prefetch: Speculation
介绍了IA64下提高乱序执行的Speculative loads
其基本思路是当一个load指令和后面的指令关联 造成无法OOO的时候 将load换成Speculative loads
其在有关联的时候不会生效 这样即使指令关联也可OOO


6.3.4 Helper Threads
在当前程序中同时做prefetch会增加程序复杂度 而且可能引起l1i的性能问题
可以单独创建一个线程做prefetch 这个线程要跟执行线程在同一core不同的硬线程 这样他们的l2 cache就是共享的
cpu_set_t self; NUMA_cpu_self_current_mask(sizeof(self), &self);
cpu_set_t hts; NUMA_cpu_level_mask(sizeof(hts), &hts, sizeof(self),
&self, 1); CPU_XOR(&hts, &hts, &self);
这个函数可用来取得cache共享的信息


6.3.5 Direct Cache Access
有一种cache miss是由输入数据造成的 现在的网卡等设备为了提高输入数据的速度都支DMA 数据会不通过CPU直接写入内存
但是这个方式有个问题 有些输入的数据很快就会被CPU处理 比如网卡接到的数据需要被分析类型 这就会产生cache miss影响处理速度
所以INTEL在他们的芯片中增加了DCA功能 其扩展了网卡到内存控制器的协议 在其中传输数据的时候可以增加DCA标志
当CPU从FSB中看到有DCA标志的数据的时候 其将把这个数据写入CACHE(当然CPU也可以根据情况乎略DCA)
这样就减少了之后CPU处理数据时候的cache miss

星期六, 四月 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 指令 而且移植性更好

星期一, 十二月 13, 2010

紫竹院

204451t-1855133155_c.jpg

星期日, 十二月 12, 2010

2010-05-22 什刹海(摄影日记)

IMG_5984

IMG_5985

IMG_6012

星期一, 十一月 01, 2010

云遮日(摄影日记)

IMG_6124

IMG_6125

星期三, 十月 27, 2010

LUBUNTU 10.10 grub.cfg更新后去掉WIN启动条目问题的解决

在一台比较老的机器上装了LUBUNTU 10.10,装好后一切OK。
升级KERNEL后grub.cfg信息被重写,再重启发现win的启动条目被去掉了。

再启动到LUBUNTU,搜了下发现有这种问题的人还不少。个人觉得
http://ubuntuforums.org/showthread.php?t=1593276
最后提供的方法比较好,但是还有缺点是下次再因为升级或者什么原因更新了grub.cfg后,仍然需要手动添加数据到文件中,有点不方便,我对这个方法作了一点小的修改。写入一次就可以了,不再需要每次更新都重新写信息到grub.clf。
下面是方法:
首先,sudo blkid取得uuid。

其次,修改/etc/grub.d/40_custom文件,增加以下行
menuentry "Microsoft Windows XP Professional (on /dev/sda1)" {
insmod part_msdos
insmod ntfs
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set XXXXXXXX
drivemap -s (hd0) ${root}
chainloader +1
}
其中XXXXXXXX换成刚取得的ID。

最后,用命令sudo update-grub更新grub.cfg文件/

这时你可以打开grub.cfg文件就可以看到win选项已经出现。

星期一, 十月 25, 2010

画像(黑白记录)

IMG_5989

星期五, 十月 22, 2010

上车(黑白记录)

IMG_6173

星期四, 十月 21, 2010

路边抽烟的人(黑白记录)

IMG_6150