Software – 夏清然的日志 https://www.qingran.net Xia Qingran Geek Blog Sun, 07 Aug 2016 09:50:33 +0000 en-US hourly 1 https://wordpress.org/?v=4.6.1 112893047 Macbook OS X 安装配置zsh https://www.qingran.net/2016/05/macbook-os-x-%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%aezsh/ https://www.qingran.net/2016/05/macbook-os-x-%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%aezsh/#respond Sun, 29 May 2016 04:20:48 +0000 https://www.qingran.net/?p=1973 换了新macbook pro retina 13后折腾了下号称终极shell的zsh。

把安装文档记录下:

terminal 默认shell换为zsh:

chsh -s /bin/zsh
安装oh-my-zsh:
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
安装autojump:
brew install autojump
编辑.zshrc,修改plugsin:

plugins=(git python adb brew autojump gradle)

加入如下内容:
alias cls=’clear’
alias ll=’ls -l’
alias la=’ls -a’
alias s=’ssh’
alias vi=’vim’
alias grep=”grep –color=auto”
alias -s html=vi # 在命令行直接输入后缀为 html 的文件名,会在 TextMate 中打开
alias -s rb=vi # 在命令行直接输入 ruby 文件,会在 TextMate 中打开
alias -s py=vi # 在命令行直接输入 python 文件,会用 vim 中打开,以下类似
alias -s js=vi
alias -s c=vi
alias -s java=vi
alias -s txt=vi
alias -s gz=’tar -xzvf’
alias -s tgz=’tar -xzvf’
alias -s zip=’unzip’
alias -s bz2=’tar -xjvf’

[[ -s ~/.autojump/etc/profile.d/autojump.sh ]] && . ~/.autojump/etc/profile.d/autojump.sh

 

修改terminal的配置为黑底:

屏幕快照 2016-05-29 11.50.50

 

修改terminal的alt按键,实现alt+f, alt+b, alt+d:

屏幕快照 2016-05-29 11.51.04

 

Done, enjoy it!

]]>
https://www.qingran.net/2016/05/macbook-os-x-%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%aezsh/feed/ 0 1973
Putty使用公钥认证时,报错:Disconnected: No supported authentication methods available(server sent:public key) 问题的解决 https://www.qingran.net/2014/01/putty%e4%bd%bf%e7%94%a8%e5%85%ac%e9%92%a5%e8%ae%a4%e8%af%81%e6%97%b6%ef%bc%8c%e6%8a%a5%e9%94%99%ef%bc%9adisconnected-supported-authentication-methods-availableserver-sentpublic-key-%e9%97%ae/ https://www.qingran.net/2014/01/putty%e4%bd%bf%e7%94%a8%e5%85%ac%e9%92%a5%e8%ae%a4%e8%af%81%e6%97%b6%ef%bc%8c%e6%8a%a5%e9%94%99%ef%bc%9adisconnected-supported-authentication-methods-availableserver-sentpublic-key-%e9%97%ae/#comments Sat, 04 Jan 2014 09:28:13 +0000 https://www.qingran.net/?p=1922 Putty使用公钥认证时,按照常规方法设置,一直报错:Disconnected: No supported authentication methods available (server sent:public key)。

如截图:

putty-error

 

找了半天没找到问题出在哪里,sshd的设置一切正常。这个做过多次居然也能错????

 

最后发现原来是 ~/.ssh/authorized_keys 文件的内容有问题,putty生成的pub文件的格式如下:


---- BEGIN SSH2 PUBLIC KEY ----
Comment: "rsa-key"
AAAAB3NzaC1yc2EAAAABJQAAAQEAvifBFJzxK0PGJVNV9ZdDGOYWvytwnFDKoaZv
Djdt7rEK+zeFzR6eU7ERhOjMPb7GfoFU/1JPwXqSN2p57T4xdtR/Qi9/XAhmQ9SY
XnfA1yNOhHXoQuoCEjOmIbOo+NmZCoKPeBob7fXV8Ar7MmJ0vUpZ+79Usm9lsvQF
zEfI/Q1NuaVoOb7s6CFyj9WcmX7Yzc3cXpIHeFzLfLTFFROohw==
---- END SSH2 PUBLIC KEY ----

而原来设置的都是在一行的格式,所以openssh不支持putty生成的此格式,需要把这些合并成一行即可:

ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAvifBFJzxK0PGJVNV9ZdDGOYWvytwnFDKoaZvDjdt7rEK+zeFzR6eU7ERhOjMPb7GfoFU/1JPwXqSN2p57T4xdtR/Qi9/XAhmQ9SYXnfA1yNOhHXoQuoCEjOmIbOo+NmZCoKPeBob7fXV8Ar7MmJ0vUpZ+79Usm9lsvQFzEfI/1NuaVoOb7s6CFyj9WcmX7Yzc3cXpIHeFzLfLTFFROohw== rsa-key

]]>
https://www.qingran.net/2014/01/putty%e4%bd%bf%e7%94%a8%e5%85%ac%e9%92%a5%e8%ae%a4%e8%af%81%e6%97%b6%ef%bc%8c%e6%8a%a5%e9%94%99%ef%bc%9adisconnected-supported-authentication-methods-availableserver-sentpublic-key-%e9%97%ae/feed/ 1 1922
使用AutoHotkey修改windows 下触摸板改为“自然滚动” https://www.qingran.net/2013/08/%e4%bd%bf%e7%94%a8autohotkey%e4%bf%ae%e6%94%b9windows-%e4%b8%8b%e8%a7%a6%e6%91%b8%e6%9d%bf%e6%94%b9%e4%b8%ba%e8%87%aa%e7%84%b6%e6%bb%9a%e5%8a%a8/ https://www.qingran.net/2013/08/%e4%bd%bf%e7%94%a8autohotkey%e4%bf%ae%e6%94%b9windows-%e4%b8%8b%e8%a7%a6%e6%91%b8%e6%9d%bf%e6%94%b9%e4%b8%ba%e8%87%aa%e7%84%b6%e6%bb%9a%e5%8a%a8/#respond Tue, 27 Aug 2013 12:41:11 +0000 https://www.qingran.net/?p=1911 启动 里即可。]]> macbook使用习惯后,都喜欢了所谓的“触摸板自然滚动”,原因很简单,和iphone、ipad等触屏保持一致。

一直寻找windows下的解决方案,经过一段时间终于找到了AutoHotkey这个软件。

下载AutoHotkey http://www.autohotkey.com/,然后安装。

新建文件reverse-roll.ahk,输入内容:

#MaxHotkeysPerInterval 200

WheelUp::
Send {WheelDown}
Return

WheelDown::
Send {WheelUp}
Return

如果有报错说是MaxHotkeysPerInterval不够的话,继续加大第一行的数值。

然后右键点击这个文件,选compile script,生成exe文件,拖动到 开始-> 启动 里即可。

]]>
https://www.qingran.net/2013/08/%e4%bd%bf%e7%94%a8autohotkey%e4%bf%ae%e6%94%b9windows-%e4%b8%8b%e8%a7%a6%e6%91%b8%e6%9d%bf%e6%94%b9%e4%b8%ba%e8%87%aa%e7%84%b6%e6%bb%9a%e5%8a%a8/feed/ 0 1911
Mac OS X词典功能使用,支持屏幕取词 https://www.qingran.net/2013/07/mac-os-x%e8%af%8d%e5%85%b8%e5%8a%9f%e8%83%bd%e4%bd%bf%e7%94%a8%ef%bc%8c%e6%94%af%e6%8c%81%e5%b1%8f%e5%b9%95%e5%8f%96%e8%af%8d/ https://www.qingran.net/2013/07/mac-os-x%e8%af%8d%e5%85%b8%e5%8a%9f%e8%83%bd%e4%bd%bf%e7%94%a8%ef%bc%8c%e6%94%af%e6%8c%81%e5%b1%8f%e5%b9%95%e5%8f%96%e8%af%8d/#respond Sun, 07 Jul 2013 15:47:16 +0000 https://www.qingran.net/?p=1880 Mac OS X自带的字典功能其实很强大:

1,在spotlight里能使用字典

2,鼠标位于希望查词的文字上,使用control + command + d也能取词翻译

3,触摸板打开三键双击取词功能也可:

1

 

 

现在要解决的问题是本身自带字典不齐的问题了,其实也很简单:

1,下载词典包转换工具,打开https://code.google.com/p/mac-dictionary-kit/downloads/list 下载其中的DictUnifier-1.1.dmg

2,下载词典 http://abloz.com/huzheng/stardict-dic/zh_CN/ 

3,使用词典包转换工具DictUnifier 转换下载的词典,转换过程较长,耐心等待。

 

convert完成后即添加词典,最好在Dictionary里选择下你需要使用的词典,以及顺序。

 

Done。

]]>
https://www.qingran.net/2013/07/mac-os-x%e8%af%8d%e5%85%b8%e5%8a%9f%e8%83%bd%e4%bd%bf%e7%94%a8%ef%bc%8c%e6%94%af%e6%8c%81%e5%b1%8f%e5%b9%95%e5%8f%96%e8%af%8d/feed/ 0 1880
Facebook HipHop on ubuntu 12.04安装笔记 https://www.qingran.net/2012/12/facebook-hiphop-on-ubuntu-12-04%e5%ae%89%e8%a3%85%e7%ac%94%e8%ae%b0/ https://www.qingran.net/2012/12/facebook-hiphop-on-ubuntu-12-04%e5%ae%89%e8%a3%85%e7%ac%94%e8%ae%b0/#respond Sat, 22 Dec 2012 11:41:09 +0000 https://www.qingran.net/?p=1859 最近看n多报道说facebook的HipHop的VM性能已经超过的编译版的,所以特意尝试了下Facebook的HipHop,现在把安装笔记记录一下。

本次安装在buntu 12.04 x86_64版本上进行,目前hiphop仅支持64bit版本:

  1. 有Internet联网电脑一台;
  2. ubuntu-12.04 x86_64 OS;
  3. 编译时间较长,需要有耐心。

升级ubuntu:

sudo apt-get update
sudo apt-get dist-upgrade

安装必要依赖包:

sudo apt-get install git-core cmake g++ libboost-dev libmysqlclient-dev libxml2-dev libmcrypt-dev libicu-dev openssl build-essential binutils-dev libcap-dev libgd2-xpm-dev zlib1g-dev libtbb-dev libonig-dev libpcre3-dev autoconf libtool libcurl4-openssl-dev libboost-system-dev libboost-program-options-dev libboost-filesystem-dev wget memcached libreadline-dev libncurses-dev libmemcached-dev libbz2-dev libc-client2007e-dev php5-mcrypt php5-imagick libgoogle-perftools-dev libcloog-ppl0 libelf-dev libdwarf-dev libunwind7-dev

git检出hiphop代码:

mkdir dev
cd dev

git clone git://github.com/facebook/hiphop-php.git
cd hiphop-php
export CMAKE_PREFIX_PATH=`/bin/pwd`/..
export HPHP_HOME=`/bin/pwd`
export HPHP_LIB=`/bin/pwd`/bin
cd ..

libevent需要重新patch:

git clone git://github.com/libevent/libevent.git
cd libevent
git checkout release-1.4.14b-stable
cat ../hiphop-php/src/third_party/libevent-1.4.14.fb-changes.diff | patch -p1
./autogen.sh
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..

libcurl需要重新patch:

git clone git://github.com/libevent/libevent.git
cd libevent
git checkout release-1.4.14b-stable
cat ../hiphop-php/src/third_party/libevent-1.4.14.fb-changes.diff | patch -p1
./autogen.sh
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..

编译jemalloc:

wget http://www.canonware.com/download/jemalloc/jemalloc-3.0.0.tar.bz2
tar xjvf jemalloc-3.0.0.tar.bz2
cd jemalloc-3.0.0
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..

以上准备工作就绪,现在开始编译hihop,本次安装是使用的hhvm模式:

cd hiphop-php
git submodule init
git submodule update
export HPHP_HOME=`pwd`
export HPHP_LIB=`pwd`/bin
export USE_HHVM=1
cmake .
make

大功告成,进入src/hhvm里,hhvm文件即是。

PS,ubuntu安装极其简单,但在一台centos6.3上装了n次才搞定。

]]>
https://www.qingran.net/2012/12/facebook-hiphop-on-ubuntu-12-04%e5%ae%89%e8%a3%85%e7%ac%94%e8%ae%b0/feed/ 0 1859
NUMA微架构 https://www.qingran.net/2011/09/numa%e5%be%ae%e6%9e%b6%e6%9e%84/ https://www.qingran.net/2011/09/numa%e5%be%ae%e6%9e%b6%e6%9e%84/#respond Thu, 08 Sep 2011 04:02:51 +0000 https://www.qingran.net/?p=1484 现在开始补日志,逐步的扫清以前写了一半的和“欠账未还的”。半年之前开的头,今天先把NUMA说完。

PC硬件结构近5年的最大变化是多核CPU在PC上的普及,多核最常用的SMP微架构:

  1. 多个CPU之间是平等的,无主从关系(对比IBM Cell);
  2. 多个CPU平等的访问系统内存,也就是说内存是统一结构、统一寻址的(UMA,Uniform Memory Architecture);
  3. CPU到CPU的访问必须通过系统总线。

结构如图所示:

SMP的问题主要在CPU和内存之间的通信延迟较大、通信带宽受限于系统总线带宽,同时总线带宽会成为整个系统的瓶颈。

由此应运而生了NUMA架构:

NUMA(Non-Uniform Memory Access)是起源于AMD Opteron的微架构,同时被Intel Nehalem采用(英特尔志强E5500以上的CPU和桌面的i3、i5、i7均基于此架构)。这也应该是继AMD64后AMD对CPU架构的又一项重要改进。

在这个架构中,每个处理器有其可以直接访问其自身的“本地”内存池,使CPU和这块儿内存之间拥有更小的延迟和更大的带宽。而且整个内存仍然可做为一个整体,可以接受来自任何CPU的访问。简言之就是CPU访问自己领地内的内存延迟最小独占带宽,访问其他的内存区域稍慢并且共享带宽。

GNU/Linux如何管理NUMA:

  1. probe硬件,了解物理CPU数量,内存大小等;
  2. 根据物理CPU的数量(不是core)分配node,一个物理CPU对应一个node;
  3. 把属于一个node的内存模块和其node相联系;
  4. 测试各个CPU到各个内存区域的通信延迟;

在一台16GB内存,双Xeon E5620 CPU Dell R710用numactl得到以下信息:

# numactl --hardware

available: 2 nodes (0-1)

node 0 size: 8080 MB

node 0 free: 5643 MB

node 1 size: 8051 MB

node 1 free: 2294 MB

node distances:

node 0 1

0: 10 20

1: 20 10

  • 第一列node0和node1就是对应物理CPU0和CPU1;
  • size就是指在此节点NUMA分配的内存总数;
  • free是指此节点NUMA的内存空闲数量;
  • node distances就是指node到各个内存节点之间的距离,默认情况10是指本地内存,21是指跨区域访问。

因为就近内存访问的快速性,所以默认情况下一个CPU只访问其所属区域的内存空间。此时造成的问题是在大内存占用的一些应用时会有CPU近线内存不够的情况,可以使用如下方式把CPU对内存区域的访问变为round robin方式。此时需要通过以下方式修改:

# echo 0 > /proc/sys/vm/zone_reclaim_mode

# numactl --interleave=all

memcached、redis、monodb等应该做以上的优化修改。

另外,如果有时间,下一篇会总结一下自己对于此问题的思考:如果自己实现一个内存池,并发挥NUMA架构的最大效能,如何设计?

参考自:

http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access

Ulrich Drepper, Memory part 4: NUMA support http://lwn.net/Articles/254445/

http://www.kernel.org/doc/Documentation/sysctl/vm.txt

 

]]>
https://www.qingran.net/2011/09/numa%e5%be%ae%e6%9e%b6%e6%9e%84/feed/ 0 1484
MMORPG网游架构分析 https://www.qingran.net/2011/07/mmorpg%e7%bd%91%e6%b8%b8%e6%9e%b6%e6%9e%84%e5%88%86%e6%9e%90/ https://www.qingran.net/2011/07/mmorpg%e7%bd%91%e6%b8%b8%e6%9e%b6%e6%9e%84%e5%88%86%e6%9e%90/#comments Thu, 14 Jul 2011 05:09:45 +0000 https://www.qingran.net/?p=1324 近两年的网游开发暂时告一段落,这段有时间总结一下。

试图从四个方面聊聊MMORPG的软件架构,:

  • 整体构架
  • 服务器端架构
  • 3D引擎
  • 游戏逻辑

要说的东西很多,其中也有很多不是我所擅长的,尽力而为吧。

]]>
https://www.qingran.net/2011/07/mmorpg%e7%bd%91%e6%b8%b8%e6%9e%b6%e6%9e%84%e5%88%86%e6%9e%90/feed/ 1 1324
使用GPU加速H.264编码分析 https://www.qingran.net/2011/07/%e4%bd%bf%e7%94%a8gpu%e5%8a%a0%e9%80%9fh-264%e7%bc%96%e7%a0%81%e5%88%86%e6%9e%90/ https://www.qingran.net/2011/07/%e4%bd%bf%e7%94%a8gpu%e5%8a%a0%e9%80%9fh-264%e7%bc%96%e7%a0%81%e5%88%86%e6%9e%90/#comments Wed, 13 Jul 2011 22:48:46 +0000 https://www.qingran.net/?p=1215 继前面的“GPGPU”和“CUDA和OpenCL”的简介后,接下来分析一个具体的使用案例:是否可以用GPU搭建一个高性能的H.264编解码服务器?

设想一个简单的需求:

  1. 把其他编码的视频转换为指定码率的H.264;
  2. 在转换过程中做一些简单的处理(例如增删水印、字幕的处理、声音的处理等);
  3. 需要封装成指定的一种container格式,比如mp4或mkv。

 

ffmpeg完成此项工作的大概过程是:

  1. 识别文件格式,打开视频文件容器,得到video_stream;
  2. 使用libavcodec把video_stream解码成原始的frame数据;
  3. 在frame的基础上做“需求2”的处理;
  4. 编码成H.264格式;
  5. 存放到指定格式的容器中(mp4或者mkv)。

“过程1”应该是一个轻量操作,且对于现有视频格式速度应该很快(播放器看片的时候不可能先等上几秒分析一把格式再开始播放吧?)。

“过程2”需要把原有的视频编码解码并转为ffmpeg内部使用的格式,速度会比上第一步慢不少,但是应该也是可以接受的。当然在码率比较高的情况下也会非常缓慢(在Pentium4时代的机器上看1080p的高清视频很卡)。

“过程3”是需要对每一帧进行处理,那么这步是可高度并行化的应该可以放到GPU进行。

“过程4”一定是最慢的一个环节:H.264需要将图像分割成很多个宏块, 然后利用视频帧图像的帧内和帧间的相关性, 采用帧内预测或帧间预测的编码模式, 对各个宏块进行压缩。然后形成帧,组成为码流。整个过程复杂,但宏块儿的处理是可以高度并行化的操作,应该可以放到GPU进行。

“过程5”和“过程1”类似。

所以如果想用GPU加速以上的过程,那么把“过程4”和“过程2”的密集计算从CPU上转到GPU上,应该是可能的发力点。

如果要设计这个系统,软件自底层到上层有几点需要考虑:

  1. 如果显卡可以指定,应该是Nvidia。在Linux下有完善的开发运行环境,且同时支持CUDA和OpenCL;
  2. 如果选定Nvidia显卡,那么根据前文的分析,使用CUDA是更好的GPU计算架构。并且应该使用最新的CUDA 4.0版本,因为在多GPU上能更方便的开发,并且GPU直接访问内存方面也做出了改进(CUDA 4.0的新特性详细见这里)。
  3. 在决定了以上基础设施后,为了提高单机的处理能力程序应该用何种架构来编写?单进程多线程还是多进程单线程?

关键在于在程序里如何更好的调用CUDA:

  1. 单进程多线程方式
    • 每个线程进行一个视频的转换,每个线程在其线程内部直接使用CUDA;
    • 有单独的CUDA线程,其他线程当需要时通知此线程进行运算;
  2. 多进程单线程
    • 每个进程进行一个视频的转换,在其进程内部各自独立的使用CUDA;
    • 有单独的GPU进程,其他进程当需要进行GPU运算的时IPC通知此进程进行;

在我看来,2-1的方式是最简单直接的,可以直接基于ffmpeg来实现,只需单把可并行化的部分从CPU移到GPU。但是CUDA 4.0是否支持这样做?这样做效率是否最高?

硬件配置上也有以下的问题:

  1. 是否需要在一个Server上配置多块儿GPU?虽说CUDA 4.0已经声称对此有很好的支持,但是其是否能利用好?另外受限于硬件瓶颈的一些限制(CPU计算能力、内存速度、总线速度),配置几块儿GPU比较合适?
  2. 如果使用ffmpeg,那么在一台拥有16核的服务器上,理论可以同时启动16个ffmpeg进程(单线程运行)。加入GPU运算后单个视频处理速度的提高是一定的,但是否还有这么大的并行能力?以及单位时间段内的处理能力是否提升?
  3. 加入GPU后硬件成本的增加是否值得?与单独使用CPU的相比单位成本是否更低?选用哪款Nvidia显卡的性价比最高?
  4. 如何看GPU的load average和top?

最后这件事情最难的一点在于:需要对CUDA、ffmpeg、H.264、硬件都有相当深入的了解才能做好这样的一个系统

]]>
https://www.qingran.net/2011/07/%e4%bd%bf%e7%94%a8gpu%e5%8a%a0%e9%80%9fh-264%e7%bc%96%e7%a0%81%e5%88%86%e6%9e%90/feed/ 2 1215
CUDA和OpenCL https://www.qingran.net/2011/07/cuda%e5%92%8copencl/ https://www.qingran.net/2011/07/cuda%e5%92%8copencl/#comments Wed, 13 Jul 2011 20:25:11 +0000 https://www.qingran.net/?p=1213 接前文“GPGPU”。

虽然我们可以使用已有的图形API来调用GPU,但是通过前文的分析,这个过程冗长且复杂。严重违反了程序员的优雅、和lazy原则。需要去学习图形学的一些知识,了解texture、shader等图形学专用概念,而且需要学习CGSL或者HLSL等shader着色语言。而且还要熟悉OpenGL和DirectX等图形学API,这一箩筐的知识没有一个一年半载是搞不定的。而且这样的方式不符合正常程序的编写习惯,所以难以优化。

最为3D程序员着想的Nvidia终于在07年搞出 CUDA ,这个架构的编程基于C 语言来进行,程序员只需要熟习CUDA的内存布局、线程层级,就能完成 CUDA 程序的开发,彻底跟那一箩筐图形学知识脱了干系,这个世界清静了。。。

CUDA 的推出是革命性的,而且OpenCL和M$的DirectX Computer GPGPU API 都基本上是采用了 CUDA 的架构和编程模型,可以说熟习 CUDA是OpenCL 的快速入门之道(Apple你肿了么?最新的mac为啥都用A卡了?)。CUDA的架构图(取自这里):

自下往上CUDA架构由四部分组成:

  1. 显卡内部的GPU的并行计算引擎;
  2. OS内核态的硬件支持,包括初始化,配置等;
  3. 用户级的驱动程序,为开发者提供的设备级的API接口;
  4. PTX指令集架构(ISA)的并行计算内核和功能.

对于开发者来说,CUDA提供了以下内容:

  • Libraries:高层次的为CUDA专门优化的BLAS, FFT等公用函数;
  • C Runtime:CUDA C语言运行库提供了支持在GPU上执行标准C语言语法喝函数,并允许其他高级语言如Fortran,Java和Python的调用;
  • Tools:NVIDIA C Compiler (nvcc),  CUDA Debugger (cudagdb),  CUDA Visual Profiler (cudaprof)

 

CUDA对OpenCL和其他编程语言的支持

由上图可知,Nvidia的OpenCL是基于CUDA Driver构建起来的,如果我们使用OpenCL那么就根据其规范编写类C语言的OpenCL内核,CUDA的Driver会接受这些计算请求并翻译给GPU运行当使用的设备级的编程接口。MS在Nvidia上的Direct Computer也是基于此,如果使用DirectX,那么需要用HLSL.编写DirectX的computer shaders,然后调CUDA Driver.

同时CUDA C Runtime的存在使我们方便的使用其他高级语言进行CUDA程序的编写,我目前常用Python就有PyCUDA的包装。

下面的内容都以直接使用CUDA的标准kernels并调用CUDA Driver API进行,这也是最直接的方法。

 

 

运算方式
CUDA支持大量的线程级并行(Thread Level Parallel),因为在GPU硬件中动态地创建、调度和执行这些线程是非常轻量的(而在CPU中,这些操作都是重量级的)。CUDA编程模型可以看作是将GPU做为协处理器的系统,CPU来控制程序整体的逻辑和调度,GPU来运行一些能够被高度线程化的数据并行部分。

CUDA程序包括串行计算部分和并行计算部分,并行计算部分称为Kernels,内核是一个可以在GPU执行的并行代码段。理想情况下,运行于CPU上的串行代码的只是清理上个内核函数,并启动下一个内核函数。

CUDA Kernels只对ANSI C进行了很小的扩展,以实现线程按照两个层次进行组织、共享存储器和栅栏同步。这些关键特性使得CUDA拥有了两个层次的并行:线程级并行实现的细粒度数据并行,和任务级并行实现的粗粒度并行。关于CUDA的线程模型需要单独拉出来说了(我看了半天文档确实没看明白,线程模型可能是CUDA最关键的一个部分,需要买块儿Geforce GTX 5xx的显卡做一个实际实验环境啊~)

 

内存操作

在 CUDA 中,GPU 不能直接存取主内存,只能存取显卡上的显存。因此,需要将数据从主内存先复制到显卡内存中,进行运算后,再将结果从显存中复制到主内存中。这些 复制的动作会受限于 PCI Express 的速度。使用 PCI Express x16 时,PCI Express 1.0 可以提供双向各 4GB/s 的带宽,而 PCI Express 2.0 则可提供 8GB/s 的带宽。当然这都是理论值。

但刚刚发布的CUDA 4.0对内存地址映射有了更好的支持:任意在CPU的malloc/new的内存,都可以通过调用cudaHostRegister注册给GPU,同样也有cudaHostUnregister来取消这个注册,而不需要cudaMemcpy。PCI-E本身就支持把一个host地址映射到device端,且DirectX和OpenGL均用这种方式来处理texture大数据。另外这个特性更方便我们编写代码:可以把一个大的CPU程序一点一点地改成GPU程序,并一步一步对比验证结果。以前这件事情需要前后都插入不少cudaMalloc和cudaMemcpy等代码,繁琐而且容易出错。

基于CUDA的复杂线程模型,内存管理的细节应该也是相当复杂,以后专文说吧。

 

执行方式

线程模型和内存管理没整懂,runtime时怎么做的就更不明白了,专文说把。

 

]]>
https://www.qingran.net/2011/07/cuda%e5%92%8copencl/feed/ 4 1213
GPGPU简介 https://www.qingran.net/2011/07/gpgpu%e7%ae%80%e4%bb%8b/ Wed, 13 Jul 2011 05:09:23 +0000 https://www.qingran.net/?p=1209 过去的一周时间研究了一下GPU做通用计算以及CUDA和OpenCL,下面会分几篇文章总结最近的成果。

图形处理单元( GPU)简称显卡是现在计算机中除CPU体系之外最复杂的一个系统。近几年来随着游戏工业的大规模发展,GPU的运算性能的增长大大超过了摩尔定律。不仅仅提高了计算机图形处理的速度和质量而且给我们提供了nb的计算平台。


GPU有两个显著的特点:

1,运算单元极多带来大并行处理能力,GPU的运算单元数量远多于CPU。例如现在民用的中端显卡Geforce GTX 570有480个CUDA cores,拥有1405 GigaFLOPS单精度浮点数运算能力。

如上图所示,CPU的大量的晶体管被cache和控制电路占用(控制指令和分支预测等操作),而ALU占用的只是一小部分。与之相反的是GPU做为专用运算器其控制电路极其简单,而且对Cache需求较小,所以大部分的晶体管用于组成各类专用运算单元和长流水线。

2,GPU拥有更快速的显存、大的显存位宽和大的显存带宽,Geforce GTX 570一般拥有1GB以上GDDR5的显存,位宽为320bit,显存频率为950MHz,且拥有152GB/s 的显存带宽。

GPU和CPU的带宽对比:

基于以上的两个特点,GPU计算优势有:

  1. 并行性。源自图形处理需要对多条绘制流水线的支持,所以GPU拥有了非常大的并行处理能力;
  2. 高密集计算。高频率、大位宽的显存 + 高速PCIe总线;
  3. 长流水线。一般来说目前显卡的流水线都有数百个指令阶段(而CPU一般只有几十个),所以GPU做为流式数据并行处理机有明显的优势。

总结一句:GPU时针对向量计算优化的并行数据处理机。

GPU编程上也有一些特殊的地方,从原理上说我们不借助CUDA或者OpenCL就能直接使用DirectX或者OpenGL直接进行GPU运算,我们可以从一个图形开发者的角度去思考如何来做。

1,纹理 == 数组

一维数组是CPU最基本的数据表达形式,同时基于此进行的偏移量计算构成了CPU编程的数据表达形式。

而对于GPU,最基本的数据排列方式是二维数组,在图形开发中,数组被做做为纹理(texture)送入GPU后进行处理。在CPU中的数组索引在GPU中改为了纹理坐标,有了纹理坐标就可以访问纹理中的每个数据,同时还必须确定坐标原点的位置。

GPU内部的额运算均是浮点数为运算,同时GPU是以一个四元组为单位进行计算的,这个四元组包括RGB三原色 + Alpha通道。

 

2,shader == kernels

传统CPU指令是以顺序、循环执行为主,例如计算1M个成员的数组的平方的结果:

for (int i=0;  i<1000000; i++)
output[i] = input[i] * input[i]

这个运算有一个非常重要的特点:那就是输入和输出的每个数组元数,它们之间是相互独立的。不管是输入的数组,还是输出结果的数组,对于同一个数组内的其他各个元素是相互独立的,我们可以不按顺序从最后一个算到第一个,或在中间任意位置选一个先算,它得到的最终结果是不变的。如果我们有一个数组运算器,或者我们有1M个CPU的话,我们便可以同一时间把整个数组一次给算出来,这样就根本不需要一个外部的循环。这就是SIMD(single instruction multiple data)。

同样的计算在OpenCL里是这样编写kernels:

const char *KernelSource = "\n" \
"__kernel void square( \n" \
" __global float* input, \n" \
" __global float* output, \n" \
" const unsigned int count) \n" \
"{ \n" \
" int i = get_global_id(0); \n" \
" output[i] = input[i] * input[i]; \n" \
"} \n" \
"\n";

可以看到,在GPU里,两个数组的相乘如此简单的一句话就搞定所有。在这里运算的GPU可编程模块,叫做片段管线(fragment pipeline),它是由多个并行处理单元组成的。在硬件和驱动逻辑中,每个数据项会被自动分配到不同的渲染线管线中去处理,到底是如何分配,则是没法编程控制的。从概念观点上看,所有对每个数据顶的运算工作都是相互独立的,也就是说不同片段在通过管线被处理的过程中,是不相互影响的。片段管线就像是一个数组处理器,它有能力一次处理一张纹理大小的数据。虽然在内部运算过程中,数据会被分割开来然后分配到不同的片段处理器中去,但是我们没办法控制片段被处理的先后顺序,我们所能知道的就是“地址”,也就是保存运算最终结果的那张纹理的纹理坐标。我们可能想像为所有工作都是并行的,没有任何的数据相互依赖性。

3,渲染 == 运算
我们准备好了纹理,写好了着色器去处理纹理,接下来我们所要做的最后一件事是告诉GPU让起来使用shader对纹理进行渲染。也就是说通过渲染一个带有纹理的四边形,我们便可以触发着色器进行运算。最后把结果存入目标纹理中。

所以整个的过程如下:

  1. 把数据通过CPU组织绘制到纹理上(CPU运算)
  2. 使用shaders处理纹理中的数据(GPU运算)
  3. 进行渲染,结果绘制到目标纹理(GPU运算)
  4. 获得目标纹理数据,CPU处理得到结果(CPU运算)

BTW,前一段时间同事老李做的骨骼动画的VTF优化(Vertex Texture Fetch)就是采用此思路。

有了上面的这些准备后,再看CUDA和OpenCL就会容易理解很多。接下来说说这些

]]>
1209
简述软件包管理系统 https://www.qingran.net/2011/07/%e7%ae%80%e8%bf%b0%e8%bd%af%e4%bb%b6%e5%8c%85%e7%ae%a1%e7%90%86%e7%b3%bb%e7%bb%9f/ https://www.qingran.net/2011/07/%e7%ae%80%e8%bf%b0%e8%bd%af%e4%bb%b6%e5%8c%85%e7%ae%a1%e7%90%86%e7%b3%bb%e7%bb%9f/#respond Tue, 05 Jul 2011 10:19:05 +0000 https://www.qingran.net/?p=1083 四月份写的一篇blog,就差个结尾,今天补上。

软件包管理是个很大的话题,希望我能说清楚这事。

上周和运营的同事头一次开会讨论了一下我们游戏上线前要注意的事。当时提到了我们软件的更新问题,由于系统运营指定的CentOS linux系统,所以我当时就说使用系统的软件包管理器yum来做软件的发布,这么合理并且靠铺的一个方案当时就被否。理由是:yum这套东西太复杂,不好使,且我们没有统一的yum源服务器。要求我们用他们自己开发的一个package方案。我暂时不知道这套package方案是如何实现的,猜测估计就是tar出来文件,然后有一个安装的bash脚本。

软件包管理系统在*nix系统中有非常重要的意义。一个能够正常工作或者提供服务的平台一般需要数百甚至数千个软件包。包管理系统就是能协调好这些软件关系,并且方便增、删、查、升级的一套系统。

先从软件开发角度考虑,一个软件安装程序需要包含以下几方面内容:

  1. 程序运行所需要的可执行文件,库文件,资源文件。并把这些文件包装成一个文件方便存放和传输;
  2. 软件包需要有版本号,并且和版本控制中代码的tag有一定的对应;
  3. 软件包能够安装、删除、升级、降级;
  4. 上面的每个过程中的每个阶段都能执行shell脚本;
  5. 软件包对第三方库的依赖性必须能够体现并规范;
  6. 软件包安装后的各个文件必须有checksum信息以获知是否被修改;
  7. 软件包本身有checksum信息,以获知其是否是原生包(debian的secure apt保证了这点,详见以前的一篇blog);
  8. 需要有统一的网络接口、工具去更新和发布软件;
  9. 能对软件进行配置和维护,相当于dpkg-reconfigure;
  10. 级联的升级或者级联的降级;
  11. 需要有工具方便的创建软件包,并且搞定以上所有的事情。

能满足以上11点需求的软件包管理器,有能力无bug的短时间搞定么?觉悟起来用现成的yum吧。

]]>
https://www.qingran.net/2011/07/%e7%ae%80%e8%bf%b0%e8%bd%af%e4%bb%b6%e5%8c%85%e7%ae%a1%e7%90%86%e7%b3%bb%e7%bb%9f/feed/ 0 1083
如何写一个为SSD优化的数据库? https://www.qingran.net/2011/07/%e5%a6%82%e4%bd%95%e5%86%99%e4%b8%80%e4%b8%aa%e4%b8%bassd%e4%bc%98%e5%8c%96%e7%9a%84%e6%95%b0%e6%8d%ae%e5%ba%93%ef%bc%9f/ https://www.qingran.net/2011/07/%e5%a6%82%e4%bd%95%e5%86%99%e4%b8%80%e4%b8%aa%e4%b8%bassd%e4%bc%98%e5%8c%96%e7%9a%84%e6%95%b0%e6%8d%ae%e5%ba%93%ef%bc%9f/#respond Mon, 04 Jul 2011 18:53:31 +0000 https://www.qingran.net/?p=1145 SSD应该是近几年来硬件技术最nb的革命,困扰计算机性能的最短木板--磁盘IO终于有了巨大的突破。而且SSD在未来的几年中会快速普及(我还琢磨着给我笔记本换SSD)。

前一段cm同学也想做一个MVCC支持的k-v数据库 ,现有的数据库都是根据几年前的硬件水平(小内存、无NUMA、机械磁盘)进行的设计的,不可能针对SSD专门优化,SSD上的MySQL性能提升应该是只用了SSD IOPS超高这一个特性。在SSD未来几年应该能广泛普及的前提下,针对SSD的数据库优化是必须的。集中查了查资料,聊聊想法,有不对的地方欢迎各位补充。

先简要的介绍一下SSD的特点。SSD没有传统机械硬盘的机械寻道时间而带来的延迟,所以IOPS性能可以达到10, 000甚至是100, 000(而15K的SAS一般在100左右),所以能提供相对于机械硬盘100+倍的的小文件读取性能。而且在连续读取方面也能带来3倍左右的性能提升。

SSD最小的写入单元是4KB的一个page,写入空白位置时是按照4KB的单位写入。但是“改写”操作是需要进行一个额外的“擦除”操作,擦除则是按照block进行(一般来说一个block是128个pages即512KB)。也就是说向一个空白区域,那么直接按照4KB对齐写入;但是如果是向已经有数据的一个区域写入新数据,那么操作过程是:整个block读入缓存 -> 修改数据 -> 擦除原有block -> 写入整个block。这个过程常称作erase-before-write,显然SSD重写已有数据区域的代价非常高。

因为SSD的erase-before-write,所以对一个区域不停的“改写”操作不仅仅带来巨大的写入延迟,也会大大减少flash的寿命。所以设计了一套均衡算法来保证其内部的每个区域都被均衡使用,简称wear leveling。wear leveling是通过SSD内部的FTL实现(Flash Translation Layer,相当于磁盘控制器,主要功能是把flash的物理地址转换为OS需要的LBA地址)。具体的方式是:首先在SSD内部分为两个block pool,一个是free block pool,一个是data block pool。顾名思义一个是尚未使用的block集合和一个已经使用的block集合。由此很容易想到的一个优化策略是当要改写一定数据时,将数据合并为block,然后直接从free block pool里取出一个无数据的区域直接写入,原有的data block pool标记为 “可擦除”,同时新使用的block进入data block pool。“可擦除”的block定期执行擦除并放入free block pool。这其实就是最常用的deferred garbage collection策略,这样做的好处是:0,写入速度较快延迟小,延迟回收而非即时擦除;1,不会反复写入同一个flash物理区域,减少物理磨损。

新的SSD TRIM技术采用了另外的一种回收策略。OS直接告诉SSD控制器:一个block的数据可以立即delete。此时SSD做的操作是把整个block读入缓存,并重置所有数据,最后回写。同时把这个块儿加入free block pool中。这样做的好处首先是把数据的控制权从OS交给了SSD FTL,FTL可以做出若干优化策略执行此事;提前把将来要进行的GC操作提前完成,避免因为没有free block pool时临时执行GC带来的延时;同时由于这些block的数据迟早要擦除,所以对SSD的寿命无影响。

同时erase-before-write还带来了一个写入放大效应,最差的情况可能是只需要改1个page以内的数据,但是却需要对1整个block进行重写。虽说上面提到的wear leveling方法会减少写入放大发生的概率,但是一但发生free block pool耗尽,需要去即时擦除data block pool的数据时,那么wear leveling就会失效,基于此SSD盘在使用重保持一个相对大的空闲空间会使其性能变化相对较小。同时随机的小文件写入的性能在某种情况下会比连续大文件写入性能下降很多,因为随机的写带来随机的擦除,从而加大写放大效应发生的概率。

同时不要忘记SSD一般会有一个64MB甚至是128MB的memory cache的存在,所以在write-back使用条件下,猜测SSD自身应该有能力去合并多次小文件写入并入一个或几个block内,并结合wear leveling做出更优化的操作。

总结一下SSD的特点:

  1. SSD有写入磨损问题,寿命有一定的影响;
  2. 最小写入单位为4KB的page,擦除的时按block进行(通常为128pages);
  3. 重写数据时由于写放大效应的存在随机写入可能会比顺序写入带来的损耗更大;
  4. 带TRIM的wear leveling理论上能大大减少随机写入的写放大效应发生的概率;
  5. 使用上尽量保持一个相对大的空闲空间;
  6. 随机小文件读取性能强大,能达到1w甚至5w IOPS,基本是现在机械硬盘的100倍+;
  7. 连续读取性能是机械硬盘的3倍左右,能达到400MB/s的吞吐能力;
  8. 读性能的延迟远低于写(传统机械硬盘读写延迟差别不大);
  9. 在空白区域的随机写和顺序写性能可能差别不大。

下面来聊聊数据库的IO特点。数据库主要分成三大块儿:最终数据文件、索引、日志。最终数据文件的读取和写入在多数场景下是大量的随机读写;索引的建立、更新和读取是随机读写;日志文件是连续读写。

先说日志文件,为了迎合传统物理硬盘连续读写性能相对优秀的特性,日志文件是采用了顺序日志记录的方式,因为需要在事务提交的时候快速响应,顺序读写减少了磁盘重新寻道的时间。只需要在日志提交时把log buffer中的数据依次写入磁盘,所以传统的数据库日志最精确的描述应该是:在连续扇区的多次小文件写入。同时索引和数据文件的update操作的随机性导致了随机写入情况的发生概率很高。全表扫描和索引文件的创建毫无疑问是一个连续大文件读写的过程。

目前想到的针对SSD特点进行优化的数据库应该有以下几点:

  1. 修改日志的顺序写入方式,因为固定目录顺序日志文件的反复写入带来很大的SSD磨损,稳定是第一;
  2. 是否考虑根据SSD的特点采用新的日志方式(我还没想好)?
  3. SSD随机读性能卓越,可以在代码层不考虑cache,直接读取源数据文件,减少同步cache的开销;
  4. 以往数据库为了尽量减少小文件的随机读而采用的一些优化方式是否可以取消?
  5. 4KB page的对齐原则;
  6. 写入数据时尽可能按照一个block的大小(512KB)去组织数据;
  7. 索引和数据文件的update操作是否可以考虑在程序内部按照block进行重组织,改多次小文件写入为一个或几个block的连续写入;

上面的第7条可能是一个过渡设计。另一个杯具是以上这些都是根据文档的纸上谈兵,到现在我还没用过SSD 🙁 ,希望以后有机会也搞一个6w的FusionIO PCIE SSD玩玩。

最后感谢万能的wikipedia,没有它的帮助不可能这么快完成这些资料的查找,主要参考以下文章:

http://en.wikipedia.org/wiki/SSD

http://en.wikipedia.org/wiki/Wear_leveling

http://en.wikipedia.org/wiki/TRIM

]]>
https://www.qingran.net/2011/07/%e5%a6%82%e4%bd%95%e5%86%99%e4%b8%80%e4%b8%aa%e4%b8%bassd%e4%bc%98%e5%8c%96%e7%9a%84%e6%95%b0%e6%8d%ae%e5%ba%93%ef%bc%9f/feed/ 0 1145
使用文件系统snapshot做数据库归档备份 https://www.qingran.net/2011/05/%e4%bd%bf%e7%94%a8%e6%96%87%e4%bb%b6%e7%b3%bb%e7%bb%9fsnapshot%e5%81%9a%e6%95%b0%e6%8d%ae%e5%ba%93%e5%bd%92%e6%a1%a3%e5%a4%87%e4%bb%bd/ https://www.qingran.net/2011/05/%e4%bd%bf%e7%94%a8%e6%96%87%e4%bb%b6%e7%b3%bb%e7%bb%9fsnapshot%e5%81%9a%e6%95%b0%e6%8d%ae%e5%ba%93%e5%bd%92%e6%a1%a3%e5%a4%87%e4%bb%bd/#respond Thu, 12 May 2011 12:17:36 +0000 https://www.qingran.net/?p=1111 昨天下午的技术讨论会上说到了数据库的按时间点的进行实时备份和归档,当时的讨论都是基于日志如何来做。

这个问题需要做到以下几点:

  • 因备份而引起的中断数据库服务的时间尽可能短;
  • 能够迅速的让数据库使用备份的数据rollback;
  • 归档的备份数据能在专门的备份机统一保存,方便本机失效后的处理;
  • 如果可能,归档备份的数据能做到增量备份,以节省备份机的磁盘空间,同时方便快速传输。

从数据库本身解决这个问题,可能受困于已有的数据库设计和代码,不非常容易。换个思路,可以基于fs的snapshot来做。

在*nix系统下功能最强的snapshot首推zfs,本身支持文件系统快照,支持增量备份,并内置了zfs send工具能直接把备份快照、或增量备份快照发送到另外一台物理机器上(也必须是zfs)。但必须使用FreeBSD 8以上或者是 OpenSolaris。但是由于公司的机器都是GNU/Linux的,退而求其次选择LVM。

在家里的E8200 + Debian 6.0.0 i386系统上做了测试,首先是使用lvm创建分区,创建了一个名为main的60GB大小的Volume Group,同时在里面建立了一个名为main0的10GB的Logical Volume挂载“/”,并格式化为ext3。

拷入6GB的数据文件,然后创建snapshot:
# lvcreate -s -L 7G -n snap-`date +%Y%m%d%H` /dev/main/main0
这一步消耗时间只有0.5s左右,而且测试了拷入20GB的数据文件,snapshot时间基本无变化,详细看截图:

然后在/dev/main/下新加入了snap-`date +%Y%m%d%H` LVM逻辑卷,可以挂载此snapshot分区:
# mount /dev/main/snap-`date +%Y%m%d%H` ~/backup

随后就可以tar成gzip包,然后rsync集中保存了。

删除snapshot:
# umount -f ~/backup# lvremove /dev/main/snap-`date +%Y%m%d%H`

对于数据库的操作来说,拿MySQL举例:

# mysql –uroot –p -h localhost
mysql> flush tables with read lock;
mysql>flush logs;
mysql>system lvcreate -s -L 7G -n snap-mysql-`date +%Y%m%d%H` /dev/main/mysqldb;
mysql>unlock tables;
mysql>quit;

就是先flush数据和日志,锁表,创建snapshot,解锁,这时就已经恢复服务。如果flush的速度够快,整个中断服务的时间在1s左右。

完毕后,即在/dev/main/snap-mysql-`date +%Y%m%d%H`下创建了一个LVM逻辑卷,如果使用,可以随时mount,然后修改mysql的数据路径,即能非常快的使用那时的数据,切换肯定也能在1s之内完成。

接下来要做的就简单了,可以mount上,然后慢慢的tar包,上传到统一备份机。

PS,今天有一位同事指出在lvm下做过snapshot后,磁盘的IO性能影响很大,这个我需要测试一下了。

]]>
https://www.qingran.net/2011/05/%e4%bd%bf%e7%94%a8%e6%96%87%e4%bb%b6%e7%b3%bb%e7%bb%9fsnapshot%e5%81%9a%e6%95%b0%e6%8d%ae%e5%ba%93%e5%bd%92%e6%a1%a3%e5%a4%87%e4%bb%bd/feed/ 0 1111
FreeBSD在线开启ipfw https://www.qingran.net/2011/05/freebsd%e5%9c%a8%e7%ba%bf%e5%bc%80%e5%90%afipfw/ https://www.qingran.net/2011/05/freebsd%e5%9c%a8%e7%ba%bf%e5%bc%80%e5%90%afipfw/#respond Tue, 10 May 2011 10:31:48 +0000 https://www.qingran.net/?p=1108 在FreeBSD 7.1 amd64版下,由于默认的内核编译选项没有并加入以下内容:

options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT

所以在启用ipfw的时候,会启用默认禁止的全部连接的规则,那么直接的后果是把ssh的连接踢下线,并切断外界到这个服务器一切端口的连接请求。

解决方案,在启用ipfw后,马上加入一条允许所有请求的规则:

kldload ipfw && ipfw add 65534 allow ip from any to any

另外需要注意一点:绝对禁止使用/sbin/ipfw -q -f flush,会导致把上面这条手动添加的开放规则删除!

同时,如果想在重启后ipfw也开启生效,那么需要这样做:

在/etc/rc.conf里加入:

firewall_enable="YES"
firewall_script="/etc/firewall.sh"

同时/etc/firewall.sh的内容是

#!/bin/sh
/sbin/ipfw -q -f flush
/sbin/ipfw add 65534 allow ip from any to any

同时自定义的ipfw规则也可以向/etc/firewall.sh中添加,比如阻止118.215.66.135到本机80端口的连接,那么加入

/sbin/ipfw add 1 deny ip from 124.193.167.1 to any dst-port 80

]]>
https://www.qingran.net/2011/05/freebsd%e5%9c%a8%e7%ba%bf%e5%bc%80%e5%90%afipfw/feed/ 0 1108
macports安装db46的jni.h No such file or directory问题解决 https://www.qingran.net/2011/05/macports%e5%ae%89%e8%a3%85db46%e7%9a%84jni-h-no-such-file-or-directory%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3/ https://www.qingran.net/2011/05/macports%e5%ae%89%e8%a3%85db46%e7%9a%84jni-h-no-such-file-or-directory%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3/#respond Sun, 01 May 2011 05:31:55 +0000 https://www.qingran.net/?p=1089 最近在我macbook上安装mercurial和git一直报错,而且都是在安装db46的时候,今天放假实在忍不了了,追了一下日志发现是jni.h头文件找不到:

 

:info:build /usr/bin/gcc-4.2 -c -I. -I../dist/.. -I/opt/local/include -I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers -pipe -O2 -arch x86_64 -fno-strict-aliasing ../dist/../libdb_java/db_java_wrap.c -fno-common -DPIC -o .libs/db_java_wrap.o
:info:build ../dist/../libdb_java/db_java_wrap.c:123:17: error: jni.h: No such file or directory

 

这下简单了就是java的开发包需要update一下,于是在此下载最新的

Java for Mac OS X 10.6 Update 4 Developer Package Download

安装,问题解决。

]]>
https://www.qingran.net/2011/05/macports%e5%ae%89%e8%a3%85db46%e7%9a%84jni-h-no-such-file-or-directory%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3/feed/ 0 1089
Mac OS X下修改控制台的option(alt)为meta键 https://www.qingran.net/2011/04/mac-os-x%e4%b8%8b%e4%bf%ae%e6%94%b9%e6%8e%a7%e5%88%b6%e5%8f%b0%e7%9a%84optionalt%e4%b8%bameta%e9%94%ae/ https://www.qingran.net/2011/04/mac-os-x%e4%b8%8b%e4%bf%ae%e6%94%b9%e6%8e%a7%e5%88%b6%e5%8f%b0%e7%9a%84optionalt%e4%b8%bameta%e9%94%ae/#respond Wed, 20 Apr 2011 17:06:34 +0000 https://www.qingran.net/?p=1078 在Mac OSX下的terminal里经常不由自主的是用alt + f、alt + b、alt + backspace来进行日常的操作,而且在emacs中alt+x+命令也是非常常用的快捷键,可是居然苹果电脑默认的option(alt)键不支持这个,只能用esc来代替了?这太不方便了。

找了一下,终于找到解决方法:
在控制台打开“偏好设置”,进入“键盘”的tab,然后把下面的”使用option键做为meta键“选中,即可完成以上功能。

PS,Mac OS X下修改网卡MAC地址:
% sudo ifconfig en0 ether aa:bb:cc:dd:ee:ff

]]>
https://www.qingran.net/2011/04/mac-os-x%e4%b8%8b%e4%bf%ae%e6%94%b9%e6%8e%a7%e5%88%b6%e5%8f%b0%e7%9a%84optionalt%e4%b8%bameta%e9%94%ae/feed/ 0 1078
sshd防止“防火墙断开空闲TCP链接”的设置 https://www.qingran.net/2011/02/sshd%e9%98%b2%e6%ad%a2%e2%80%9c%e9%98%b2%e7%81%ab%e5%a2%99%e6%96%ad%e5%bc%80%e7%a9%ba%e9%97%b2tcp%e9%93%be%e6%8e%a5%e2%80%9d%e7%9a%84%e8%ae%be%e7%bd%ae/ https://www.qingran.net/2011/02/sshd%e9%98%b2%e6%ad%a2%e2%80%9c%e9%98%b2%e7%81%ab%e5%a2%99%e6%96%ad%e5%bc%80%e7%a9%ba%e9%97%b2tcp%e9%93%be%e6%8e%a5%e2%80%9d%e7%9a%84%e8%ae%be%e7%bd%ae/#respond Tue, 22 Feb 2011 02:51:06 +0000 https://www.qingran.net/?p=996 最近发现公司的的内网ssh登陆上服务器后不操作一段时间就会断线,同时如果一直在操作或有屏幕输出(类似tail -f /var/log/apache2/access.log),那么ssh就不会断线。

猜测是公司的防火墙有“断开空闲TCP链接”的策略,在/etc/ssh/sshd_config 内加入:

ClientAliveInterval = 15
ClientAliveCountMax = 100

ClientAliveInterval的含义是每过15s,sshd会向ssh client发出一个询问是否在线的请求,正常的ssh client都会予以回应;同时ClientAliveCountMax设定了这种询问的最大失败值,在本例中如果sshd向client发出了100次讯问均没有得到回应,那么sshd会主动断开此ssh链接。

]]>
https://www.qingran.net/2011/02/sshd%e9%98%b2%e6%ad%a2%e2%80%9c%e9%98%b2%e7%81%ab%e5%a2%99%e6%96%ad%e5%bc%80%e7%a9%ba%e9%97%b2tcp%e9%93%be%e6%8e%a5%e2%80%9d%e7%9a%84%e8%ae%be%e7%bd%ae/feed/ 0 996
[转]热门3D游戏视觉效果名词简介 https://www.qingran.net/2011/02/%e8%bd%ac%e7%83%ad%e9%97%a83d%e6%b8%b8%e6%88%8f%e8%a7%86%e8%a7%89%e6%95%88%e6%9e%9c%e5%90%8d%e8%af%8d%e7%ae%80%e4%bb%8b/ https://www.qingran.net/2011/02/%e8%bd%ac%e7%83%ad%e9%97%a83d%e6%b8%b8%e6%88%8f%e8%a7%86%e8%a7%89%e6%95%88%e6%9e%9c%e5%90%8d%e8%af%8d%e7%ae%80%e4%bb%8b/#respond Fri, 18 Feb 2011 18:25:18 +0000 https://www.qingran.net/?p=920 一部又一部的游戏大作降临,每个游戏都声称要给玩家“真实”的体验。当然既然叫做游戏就不可能是真实的,但游戏制作商们都在不断想办法使游戏更加接近现实,使用各种3D效果去模拟现实中的种种现象。可能还有不少玩家朋友对这些视觉效果名词还不大了解,于是有了本文。本文就是用简单的语言,简要地介绍目前应用在游戏中的一些比较热门的视觉效果。

主要名词:
#1 –
动态模糊(Motion Blur
#2 –
景深(Depth Of Field
#3 –
软阴影(Soft Shadow
#4 –
高动态光照(High Dynamic Range
#5 – 凹凸
贴图技术
#6 – 法线贴图
#7 – 视差贴图

#8 –
次表面散射(SubSurface Scattering
#9 –
体积云/雾(Volumetric Clouds/Fog
#10 –
体积光(Volumetric Light
#11 – SpeedTree
#12 –
延迟渲染(Deferred Rendering

一、动态模糊(Motion Blur

3D游戏玩家会问这么个问题:为什么每秒24帧的速度对于电影来说已经足以获得很流畅的视觉效果,而对于电脑游戏来说却非常不流畅?原因很简单,摄像机在工作的时候并非一帧一帧绝对静止地拍摄,它所摄下的每一帧图像已经包含了1/24秒以内的所有视觉信息,包括物体在这1/24秒内的位移。如果在看电影的时候按下暂停键,我们得所到的并不是一幅清晰的静止画面,而是一张模糊的图像。


传统的电脑3D图像做不到这一点,游戏里的每一帧就是一幅静止画面,如果你在运动的过程中抓一张图片下来,得到的肯定是一幅清晰的静态图。所以,动态模糊技术的目的就在于增强快速移动场景的真实感,这一技术并不是在两帧之间插入更多的位移信息,而是将当前帧同前一帧混合在一起所获得的一种效果。

《极品飞车:卡本峡谷》采用的动态模糊,但效果不好,表现太夸张,时间长很容易让人感到不适:


《孤岛危机》的动态模糊改善了很多,表现效果也好了很多,据称是得益于DX10引入了几何渲染器:


二、景深(Depth Of Field

有摄影基础的朋友一定都熟悉“景深”这个词。如果非要解释这个词的话就是“在摄影机镜头或其他成像器前,沿着能够取得清晰图像的成像器轴线所测定的物体距离范围”。说得再简单一些,就是距离不同的景物,呈现出有些地方清楚有些地方模糊的效果。这种效果能够更加突出需要反应的焦点,让画面的主题更加鲜明。

我们观察下面的两张图片,就能非常明显的看出景深的效果。在第一张图片中,手持长棍的忍者是清楚的,后面的景物时模糊的。而在第二张图片中,焦点移到了后面的景物上,前景的忍者反而变成了模糊的效果了。这样的效果更符合人肉眼对自然环境观察的结果,也就因此令玩家的感受更真实:


《使命召唤4》使用的景深效果:


FPS游戏中景深效果往往用在枪械的瞄具上。在游戏中使用机械瞄具的时候,人的注意力必然高度集中,准心以外的区域都模糊。

《孤岛危机》中景深效果大放异彩:


三、软阴影(Soft Shadow

从字面上直译过来就是“软阴影”,不过叫“柔和阴影”似乎更合适。我们知道生活中很多阴影的过渡都是有渐变,而软阴影的作用就是要模拟这种效果,在阴影周边制造虚化的效果。软阴影本身并不是指一种技术,而是指通过采用某种技术达到的效果。

在说软阴影前先说说阴影的生成方法。一般在游戏中采用的阴影生成方法有两种:Shadow Mapping(阴影映射)和Shadow Volumes(体积阴影)。

Shadow Mapping(阴影映射)是一种图像空间的技术,它是在以光源位置作为视点的情况下渲染整个场景的深度信息,然后再使用这些深度信息去决定场景的哪一部分是处于阴影之中。它有锯齿并且依赖z-缓冲技术。由于可以在不减少帧率的情况下达到真实感光照和阴影效果,编辑器允许在场景中放置任意数目的静态光源,它会为每个面预计算光流量(light flow)和静态阴影,因此现代商业3D游戏中多数都会使用到阴影映射。阴影映射效果的一个影响因素是Shadow Map Size,如果size(尺寸)小,会导致阴影边缘模糊不清、闪烁、出现大型锯齿。增大size能提高阴影质量,但帧速会受到影响。

Shadow Map Size太小(上图),增大Size之后(下图)


对于在阴影映射下实现软阴影,通常是在阴影边界进行高精度超级采样的方法,如虚幻3引擎就是进行16X的超级采样,这就是软阴影消耗系统资源大的原因。


《生化冲击》使用阴影映射,表现出色:



《西部狂野》的Shadow Map Size高达2048*2048,生成的阴影效果非常好,当然对硬件要求也高:



《尘埃》的Shadow Map Size更是前所未有地达到了4096*4096,阴影柔化效果也很到位,它的硬件要求大家也是清楚的:



《孤岛危机》的阴影效果当然是顶级的了,除了使用阴影映射,还使用了大量高级技术(如高精度采样、屏幕空间环境光遮蔽等):


Shadow Volumes(体积阴影)是一种基于几何形体的技术,它需要几何体在一定方向的灯光下的轮廓去产生一个封闭的容积,然后通过光线的投射就可以决定场景的阴影部分(常常使用模板缓冲去模拟光线的投射)。这项技术是像素精确的,不会产生任何的锯齿现象,但是与其他的技术一样,它也有缺点。最主要的两个问题一是极度依赖几何形体,二是需要非常高的填充率。同时,体积阴影也相当依赖CPU,视觉效果方面是产生的阴影比较“硬”。
目前使用体积阴影的游戏不多,《DOOM3》和《F.E.A.R.》就是典型,在游戏中仔细观察你会发现它们的阴影和其他游戏的明显不同:



F.E.A.R.》是第一个采用了软阴影的游戏,它的软阴影实现方法是在光源在自身附近进行自我复制,产生多个不同亮度的阴影再混合起来,这种软阴影效果似乎不怎么理想,边缘看起来有层状感,系统资源开销也大:


四、高动态光照(High Dynamic Range

很多人对HDR的第一感觉就是“太亮了、好刺眼、受不了”。其实HDR并不是像许多玩家理解的那样就是简单的“高亮”,不是让画面有更大的亮度或是对比度。大家都知道,当人从黑暗的地方走到阳光下时,我们的眼睛会不由自主的眯起来,那是因为在黑暗的地方,人为了更好的分辨物体,瞳孔张开很大,以便吸收光线;而突然到了光亮处瞳孔来不及收缩,视网膜上的视神经无法承受如此多的光线,人自然会眯上眼睛阻止大量光线冲击视神经。

我们的眼睛非常敏感,而电脑就不具备这种功能,因此就通过HDR技术在一瞬间将光线渲染得非常亮,然后亮度逐渐降低。所以,HDR的最终效果应该是亮处的效果是鲜亮的,而黑暗处你也可以清晰的分辨物体的轮廓,位置和深度,而不是以前的一团黑。动态、趋近真实的物理环境是HDR的特效表现原则:

高亮的部分仍保持了相当丰富的细节


HDR
并不仅仅是反射的光强度要高。在游戏中,如果你盯着一个面向阳光直射的物体,物体表面会出现丰富的光反射;如果盯着不放,物体表面的泛光会渐渐淡出,还原出更多的细节。HDR特效是变化的,因此称做高动态光照。

HDR是分种类的,一般按可精度分为:Int16(整数)、FP16(浮点)、FP32等等,数字越大精度越高,运算量当然也越大。其中Int格式的HDRSM2.0下即可实现(如半条命2:失落的海岸线、第一章、第二章),FP格式要SM3.0或以上才能实现(目前有HDR的游戏基本都是FP格式),在DX10HDR的精度已经提升到FP128

说到HDR不得不提另外一个特效:BLOOMBLOOM也能实现和HDR类似的效果,但BLOOM的是静态的,HDR是动态渐变的,BLOOM在细节表现、明暗对比不如HDR,这是BLOOMHDR的重要区别。实现HDR效果的系统资源开销也比BLOOM大。

3Dmark06中绚丽的HDR效果:


《无限试驾》的HDR效果我是比较认同的:



《彩虹6号:维加斯》、《生化冲击》的都不错:



《孤岛危机》的HDR使用已经非常成熟:



游戏中贴图是2D的,如果在游戏中换个角度看的话,很容易就会发现墙面没有任何立体感,砖纹看上去非常假!为了让2D贴图看上去也有3D立体效果,就诞生了多种贴图技术,比如凹凸贴图、法线贴图、位移贴图、视察映射贴图等。

五、凹凸贴图(Bump Mapping

凹凸贴图技术简单说起来是一种在3D场景中模拟粗糙表面的技术,将带有深度变化的凹凸材质贴图赋予3D物体,经过光线渲染处理后,这个物体的表面就会呈现出凹凸不平的感觉,而无需改变物体的几何结构或增加额外的点面。例如,把一张碎石的贴图赋予一个平面,经过处理后这个平面就会变成一片铺满碎石、高低不平的荒原。当然,使用凹凸贴图产生的凹凸效果其光影的方向角度是不会改变的,而且不可能产生物理上的起伏效果。

凹凸贴图在今天看来已经是老的不能再老的一种技术了,虽然能够获得凹凸的效果,但是凹凸的程度非常受限制,基本上只能做出一些简单的浮雕效果来。这种技术通常用在一些观察视角变化很小的情况上,例如地面,墙壁,远处的一些模型等等,如果角度稍微一大,你就会发现那些凹坑其实是根本不存在的:


六、法线贴图(Normal Mapping

法线贴图技术通过计算高细节度模型的法线信息并将其保存在一张高压缩比(3DC/DC5)的法线贴图之中,然后将这张法线贴图贴用于低细节模型上代替原型的多边形曲面的光照计算,从而等到一个低多边形、高细节的3D模型。这样做就能在保证模型细节的情况下,大幅度降低场景的多边形数目。法线贴图目前已经广泛应用于3D游戏中。

视觉效果达到1亿多边形的场景,通过线框显示发现只用了50万多边形。(虚幻3引擎场景)


法线贴图在《孤岛危机》里的应用,立体感表现得非常好:


七、视差贴图(Parallax Mapping

视差贴图技术我们其实应该称之为视差遮蔽贴图技术,因为在这一技术中,会对纹理的坐标做变换,一些凸出的纹理会遮蔽到其他的纹理,这样就会看起来具备更好的凹凸的感觉了。视差贴图技术的实现原理,其实和法线贴图是一样的,都是根据法线贴图进行的处理。视差贴图比法线贴图提供更好的视觉效果,而且跟法线贴图有同一个目的:在保证模型细节的情况下,大幅度降低场景的多边形数目。

S.T.A.L.K.E.R.》中的视差贴图效果,砖块和石板上的凹痕表现十分生动:


《孤岛危机》中使用的视差消隐贴图,堪称目前Bump mapping技术的极致!逼真的鹅卵石让人留下深刻的印象!:


八、次表面散射(SubSurface Scattering,简称3S

目前使用次表面散射效果的游戏极少,似乎就只有《孤岛危机》。它主要用于模拟不完全透明材质内部表现出的一种真实光影特效。当灯光照射到玻璃或清澈的液体表面时,灯光会穿透这些介质,3S效果可用来模拟灯光进入介质内部后发生的散射。

《孤岛危机》中树叶的透光性:


3S的另一个重要用处在于表现光源照射下的人物皮肤,换句话说,要想表现真实的皮肤材质,3S效果必不可少。目前的许多游戏在人物皮肤的渲染上就因为缺乏3S效果而显得塑料化、橡胶化。

F.E.A.R.》人物缺乏3S效果,塑胶感较大:



CryEngine 2
使用3S效果生成的人物脸部:


《孤岛危机》的人物脸部效果非常出色:



照片级的CG图,同样采用了3S,效果惊人!:


九、体积云/体积雾(Volumetric Clouds/Fog

简单地说,在游戏中的体积云就是使用图像引擎来模拟真实云雾半透明、无规则的表现效果。

在早期游戏中,实现云雾烟火效果的方式常常使用贴图的方法。CS中可以很清楚的看到这一点。将烟雾品质改为“低”时,CS中烟雾的表现如同灰白色的墙壁一般。采用云雾烟火贴图的游戏经常会降低透过云雾贴图之后远景效果,甚至替换远景贴图,仔细观察就会发现,而体积云则不会。

CS的烟雾弹效果,可以看到层状的材质:


《使命召唤4》在关闭烟雾柔化后,也表现出同样效果:


事实上,体积云本身的定义就比较模糊,欧美业界的观点是:通过3D引擎实时生成的、能够随时间流逝而自动改变的、能够和物力引擎互动产生变化的(比如飞机飞过云雾散开),才能称为体积云/体积雾。

《孤岛危机》中采用的就是体积云效果:


《冲突世界》也大量使用了体积云:


《生化冲击》在DX10才能开启体积云效果:


十、体积光(Volumetric Light
先来看下面一个现实世界的光线图,在3D图形中要实现这种效果就是体积光(Volumetric Light)。目前的游戏都是在DX10下才有体积光效果,看来是得益于DX10的渲染架构的改进,使体积光这种高级特效得以更容易地在游戏中实现。


《冲突世界》的招牌DX10效果-体积光:



《孤岛危机》作为DX10的招牌游戏当然少不了体积光效果:


CryEngine 2演示视频,可以注意到,当主角经过时,枪支会被透射的光线照耀到:


《孤岛惊魂》《半条命2:失落的海岸线》的光束效果似乎比较生硬、呆板,光照强度一成不变,也不会留下恰当的阴影,显然是预先安排好的,并非真正的体积光效果:


十一、SpeedTree

SpeedTree是一个专门的植被引擎。其技术最大的特征就是可以在使用极少多边形的情况下创造出高度逼真的树木和植物,并且可以调整风速效果,使得这些植物随着风的吹动而真实地摇动。游戏开发者就可以直接在特定地形上生成整个森林,无需将树一棵一棵地设置在相应地点上,大大提高了工作效率。并且通过SpeedTree的代码优化技术,画面上数量繁多的枝叶不会对画面帧数造成太大影响。

虚幻3引擎整合了SpeedTree技术,虚幻3引擎制作的游戏都可以用SpeedTree技术快速生成大量高品质的植被:


《上古卷轴4》用SpeedTree创造了一个神奇的世界:


《冲突世界》也使用了SpeedTree技术:


十二、延迟渲染(Deferred Rendering

延迟渲染技术可以说是未来游戏的发展趋势,其原理是先把全景多边形物体的信息比如位置、法线面、各种贴图渲染到G-Buffer(缓冲区)内,延迟打光步骤。

延迟渲染可以避免在渲染过程中出现无效渲染(渲染器在运算过程中做了某些无用功)的现象和提高出现大量复杂、耗时的像素渲染时的工作效率。

延迟渲染可以创建大量的点光源以及产生真实的光照结果,提高画面的真实度;也可以避免对不可见的点进行光照,节省了资源。不过,延迟渲染并不是很适合DX9,在目前的硬件上必须以牺牲MSAA(多重取样抗锯齿)为代价(使用了延迟渲染的《S.T.A.L.K.E.R.》、《幽灵行动:尖峰战士》都无法支持多重取样抗锯齿),而在新的DX10硬件上则没有问题 。最新版本的UE3引擎已经为DX10做了优化,MSAA已经完全没有问题(《战争机器》PC版在DX10下即可开启抗锯齿),但是之前面世的几个采用UE3的游戏都是基于老版本的UE3开发,所以对MSAA的支持还存在各种问题。对于目前的几个UE3引擎游戏,它们并未使用延迟渲染技术。

目前使用了延迟渲染技术的游戏有《S.T.A.L.K.E.R.》、《幽灵行动:尖峰战士》系列。


]]>
https://www.qingran.net/2011/02/%e8%bd%ac%e7%83%ad%e9%97%a83d%e6%b8%b8%e6%88%8f%e8%a7%86%e8%a7%89%e6%95%88%e6%9e%9c%e5%90%8d%e8%af%8d%e7%ae%80%e4%bb%8b/feed/ 0 920
Trac、Mercurial集成项目管理工具组建 https://www.qingran.net/2011/01/trac%e3%80%81mercurial%e9%9b%86%e6%88%90%e9%a1%b9%e7%9b%ae%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%e7%bb%84%e5%bb%ba/ https://www.qingran.net/2011/01/trac%e3%80%81mercurial%e9%9b%86%e6%88%90%e9%a1%b9%e7%9b%ae%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%e7%bb%84%e5%bb%ba/#respond Thu, 13 Jan 2011 04:12:34 +0000 https://www.qingran.net/?p=775 我们的项目已经进行了半年,马上进入了第3个季度,慢慢的需求管理、缺陷管理的建立也需要提上日程。

从走在前面的3D引擎的开发状况看,需要有一个良好的bug管理系统来管理bug、记录需求等,于是决定用一个项目管理工具来实施,直接上Trac,并且要做到和我们的开发的版本管理工具Mercurial完全集成,Mercurial的安装见链接

首先ubuntu的apt reposity里只有trac 0.11.7,所以需要下载trac-0.12.1,导致一些安装需要手工安装。

使用0.12.1在于支持i18n,支持多个source reposity等,并且基于0.12版本的plugin较多。

[准备工作]

系统是ubuntu 10.04 LTS。

首先安装trac所需要的支持环境,采取先安装trac,然后再移除的方式安装依赖包:
apt-get install trac && dpkg -P trac

安装Genshi 0.6版本(下载),trac 0.12依赖此:
tar -xvzf Genshi-0.6.tar.gz && cd Genshi-0.6 && python setup.py install

安装Trac 0.12.1:
tar -xvzf Trac-0.12.1.tar.gz && cd Trac-0.12.1 && python setup.py install

[配置apache2]

目前使用mod_python方式运行trac,wsgi方式配置Trac mainnav一直出不来,很郁闷:(
apt-get install libapache2-mod-python

因为是通过 http://ipaddr/trac 访问的,修改/etc/apache2/sites-available/default,加入以下内容:

<Location /trac>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonInterpreter main
PythonOption TracEnv /data/trac/core-trac
PythonOption TracUriRoot /trac
SetEnv PYTHON_EGG_CACHE /tmp
AuthType Basic
AuthName "core trac password"
SetEnv PYTHON_EGG_CACHE /tmp
AuthUserFile /etc/apache2/hg.passwd
Require valid-user
</Location>

初始化trac库:
cd /var/www && mkdir trac && trac-admin trac/ initenv && trac-admin trac/ permission add xiaqingran TRAC_ADMIN

指定TRAC_ADMIN用户:
trac-admin trac/ permission add xiaqingran TRAC_ADMIN

[配置trac]

首先配置用户的trac权限,觉的命令行麻烦就用webadmin来吧。

配置mercurial,在trac中能浏览mercurial中的代码,能在commit代码的时候自动close ticket,并且把diff加入提案:

安装mercurial-plugin:
svn co http://svn.edgewall.com/repos/trac/plugins/0.12/mercurial-plugin
制作egg文件:
cd mercurial-plugin && python setup.py bdist_egg

进入webadmin界面,然后再plugin选项里安装刚刚生成的egg mercurial-plugin/dist/TracMercurial-0.12.0.23dev_r9953-py2.6.egg

重启apache2,刷新页面,看plugin是否enabled。

同时在plugin里把Trac 0.12.1里把tacopt.ticket.commit_updater.*下的插件打开,同时把TracMercurial里的所有插件enable。

进入WebAdmin -> Version Control -> Repositories加入相关的版本库,名称为client,版本库类型是hg,目录就选在在服务器上的hg目录。

[配置mercurial]

设定mercurial的hooks,使其在hg push时能同步修改trac,编辑hg服务器端的.hg/hgrc,加入以下两段:
[hooks]
commit = trac-admin /var/www/trac/ changeset added client %HG_NODE%
incoming = trac-admin /var/www/trac/ changeset added client %HG_NODE%

mercurial提交的时候按照此格式编写commit log:
- *Fixes #123* - to reference this changeset and close #123 ticket with the default status *fixed*

完毕,enjoy it.

]]>
https://www.qingran.net/2011/01/trac%e3%80%81mercurial%e9%9b%86%e6%88%90%e9%a1%b9%e7%9b%ae%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%e7%bb%84%e5%bb%ba/feed/ 0 775
删除Python easy_install安装软件 https://www.qingran.net/2011/01/%e5%88%a0%e9%99%a4python-easy_install%e5%ae%89%e8%a3%85%e8%bd%af%e4%bb%b6/ https://www.qingran.net/2011/01/%e5%88%a0%e9%99%a4python-easy_install%e5%ae%89%e8%a3%85%e8%bd%af%e4%bb%b6/#comments Wed, 12 Jan 2011 14:48:51 +0000 https://www.qingran.net/?p=791 python的easy_install是很方便的安装体系,可是一般来说setup.py没有deinstall的选项,那么如何删除已经安装的egg呢?

easy_install -mxN Genshi
然后下面类似的提示:

install_dir /usr/local/lib/python2.6/dist-packages/
Processing Genshi-0.6-py2.6.egg
Removing Genshi 0.6 from easy-install.pth file

Installed /usr/local/lib/python2.6/dist-packages/Genshi-0.6-py2.6.egg

Because this distribution was installed --multi-version, before you can
import modules from this package in an application, you will need to
'import pkg_resources' and then use a 'require()' call similar to one of
these examples, in order to select the desired version:

    pkg_resources.require("Genshi")  # latest installed version
    pkg_resources.require("Genshi==0.6")  # this exact version
    pkg_resources.require("Genshi>=0.6")  # this version or higher

然后删除目录:

rm -rf /usr/local/lib/python2.6/dist-packages/Genshi-0.6-py2.6.egg

]]>
https://www.qingran.net/2011/01/%e5%88%a0%e9%99%a4python-easy_install%e5%ae%89%e8%a3%85%e8%bd%af%e4%bb%b6/feed/ 1 791