2007年5月14日星期一

桌上足球比赛闯入四强

今天中午连赛两场,第一场由于对方防守队员比较弱,被我狂轰乱炸一通,最终进了16个球(8分钟)。其实还是蛮惊险的,上半场一路领先,结束时我方以 10:4 领先。下半场对方发起了猛烈的进攻,比分竟然被追为 10 平。我方又发扬愈战愈勇的精神,连续进了六个球,直接打击了对方的嚣张气焰,最终将比分锁定为 16:11。呵呵,这场打的确实爽啊,看得观众们惊呼不断。

第二场迎战夺冠热门队,对方的实力确实很强。进攻球员非常的沉着冷静,我方后卫很难招架;而对方防守队员也不弱。上半场结束时落后一分,本想在下半场追回,不想下半场对方的后卫加强了防守,竟然没有什么机会破门,相比之下,我方又被连进 N 球,最终败北。

在前两场连败的情况下,我队以三负一胜的战绩排名第四(有一队全败),顺利晋级四强。接下来就是淘汰赛了,各个对手都非常的强悍。如何确定一个有效的战术,还真是一个问题。如果防守队员稍加训练,就能有效的阻止前锋的进攻,所以后防线确实是一个非常重要的事情啊。

酒精是脑细胞杀手

前两天有个兄弟举办婚宴,喝了一点白酒,直接导致我当天下午兼晚上头晕,脑袋象生锈了一般,无法思考。睡了一觉起来,仍觉得晕晕糊糊,看来酒精的确是脑细胞杀手。以后发誓不饮白酒,身体先天不适合喝酒。

给 TeX 增加一个中文字体

今天在网上看到方正发布了一款徐静蕾的手写字体,看上去蛮清秀的,于是乎就下载了一个(莫 BS 我),准备在自己的 TeX 系统中使用。记得以前写过一个在 TeX 下增加中文字体的脚本,现在找不到了,不过好在 dvipdfmx 的字体还是很容易配置的。简单介绍一下,添加字体的过程分为三步:

第一步:为 TeX 增加字体配置
(1) 在 tex/latex/CJK/UTF8/ 下增加一个 c70jinglei.fd,内容按照 c70song.fd 替换 song 为 jinglei 即可;
(2) 生成 tfm/enc 文件,具体命令为:
ttf2tfm jinglei.ttf -q -w unijinglei@your_path/Unicode.sfd@
move *.tfm ../tfm/unicode/unijinglei;
move *.enc ../enc/pdftex/unicode/unijinglei;
(3) 运行 texhash;

第二步:为 dvipdfmx 增加字体配置
(1) 修改 tex/fonts/map/dvipfdm/cid-x.map,在其中增加一行即可;

第三步:为 ttf2pk 增加字体配置
(1) 修改 tex/fonts/ttf2pk/ttfonts.map,增加一行即可;

第四步:为 dvips 增加字体配置
(1) 这个需要生成 Type1 字体,比较麻烦,暂且不做了,dvipdfmx 挺好用的

If you can't read Chinese, it is ok for you to ignore this article. It is about adding a Chinese font in TeX system.

2007年5月9日星期三

Predefined Macros in gcc

gcc has many predefined macros, which can be list by

cpp -dM /dev/null

2007年4月17日星期二

Make xdvi use Type1 fonts

Traditionally, xdvi use pk fonts to display preview which are usually generated from Truetype fonts. This process could be slow and the generated pk fonts could consume a lot of disk space. Actually, xdvi can use Type1 fonts. If you have Type1 fonts on your disk, xdvi can use them to display preview and save lots of time. Here is how to do that:

Step1: copy xdvi.cfg from TEXMF/xdvi/ to TEXMF-LOCAL/xdvi;
Step2: add the dvips map file into xdvi.cfg;
Step3: texhash;

Now no pk fonts were generated anymore. Chinese fonts just looks great.

For more details, refer to http://xdvi.sourceforge.net/README.t1fonts

2007年4月11日星期三

Some Experiences on Big Project

Principle1: do NOT give more than necessary access permissions, for example:
1. define variables used exclusively in only one function as local;
2. define variables used exclusively in only one file as static;
3. declare read only argument as const *;

Principle2: tag code snippet according to its semantics;
1. declare all global variables with a tag like GLOBAL, so that you can list them;
2. use static_cast instead of forced type conversion;

Principle3: locality in SE:
1. gather all operations on some type of object in one or two files;

2007年3月31日星期六

Time to Wakeup a Thread in Linux

Abstract:
In multithreaded programming, it is sometimes desirable to have some process blocked for a specific event to happen. For better response time, there maybe two method to implement this, one approach is that the process spinned on a flag indicating the arrival of the event, and the other is the process blocked on a conditional variable and wakenup by another thread when the event happens. Here we compare the effectiveness of these two methods.

Test Platform:
OS: Linux 2.6.18-1.2798.fc6 #1 SMP x86_64 GNU/Linux
CC: gcc version 4.1.1 20061011 (Red Hat 4.1.1-30)
CFLAGS: -Wall -O2
LDFLAGS: -lrt -lpthread
CPU: Dual Core AMD Opteron(tm) Processor 270
System: 2 processors

Response Time(averaged among 500 run):
usleep(1): 39928260.000000 ns
clock_nanosleep(1): 39835940.000000 ns
pthread_cond_wait: 346940.000000 ns

Source Code for Test Program:
I can't find anywhere in this blog to upload files, so until I find it, the source code may not be publicly available. Maybe you can teach me howto upload files on blogger.com. Just drop me a email.

Conclusions:
Neither usleep(1) nor clock_nanosleep(1) is good for response time, use pthread_cond_wait() is a good choice with the additional advantage of releasing CPU time for other processes/threads.

2007年3月28日星期三

how to add a directory in cvs?

There are two circumstances:

(1) the directory is empty, then use

$ cvs add dir_name

(2) the directory is not empty, in such case, you use

$ cvs import dir_name path_in_repository vendor_tag release_tag

instead.

关于 make 的一些乱七八糟的东西

Abstract


(1) How to make the output of 'make' more readable(.SILENT)?
(2) Why can't I understand some strange makefiles(Multiple Rules for One Target)?
(3) How to boost make performance(-j nr_jobs)?

4.9 Special Built-in Target Names

Certain names have special meanings if they appear as targets.

.PHONY
The prerequisites of the special target .PHONY are considered to be phony targets. When it is time to consider such a target, make will run its commands unconditionally, regardless of whether a file with that name exists or what its last-modification time is. See Phony Targets.


.SUFFIXES
The prerequisites of the special target .SUFFIXES are the list of suffixes to be used in checking for suffix rules. See Old-Fashioned Suffix Rules.


.DEFAULT
The commands specified for .DEFAULT are used for any target for which no rules are found (either explicit rules or implicit rules). See Last Resort. If .DEFAULT commands are specified, every file mentioned as a prerequisite, but not as a target in a rule, will have these commands executed on its behalf. See Implicit Rule Search Algorithm.


.SILENT
If you specify prerequisites for .SILENT, then make will not print the commands to remake those particular files before executing them. The commands for .SILENT are not meaningful.

If mentioned as a target with no prerequisites, .SILENT says not to print any commands before executing them. This usage of `.SILENT' is supported only for historical compatibility. We recommend you use the more selective ways to silence specific commands. See Command Echoing. If you want to silence all commands for a particular run of make, use the `-s' or `--silent' option (see Options Summary).


.EXPORT_ALL_VARIABLES
Simply by being mentioned as a target, this tells make to export all variables to child processes by default. See Communicating Variables to a Sub-make.


.NOTPARALLEL
If .NOTPARALLEL is mentioned as a target, then this invocation of make will be run serially, even if the `-j' option is given. Any recursively invoked make command will still be run in parallel (unless its makefile contains this target). Any prerequisites on this target are ignored.

Any defined implicit rule suffix also counts as a special target if it appears as a target, and so does the concatenation of two suffixes, such as `.c.o'. These targets are suffix rules, an obsolete way of defining implicit rules (but a way still widely used). In principle, any target name could be special in this way if you break it in two and add both pieces to the suffix list. In practice, suffixes normally begin with `.', so these special target names also begin with `.'. See Old-Fashioned Suffix Rules.


4.11 Multiple Rules for One Target

One file can be the target of several rules. All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target. If the target is older than any prerequisite from any rule, the commands are executed.

There can only be one set of commands to be executed for a file. If more than one rule gives commands for the same file, make uses the last set given and prints an error message. (As a special case, if the file's name begins with a dot, no error message is printed. This odd behavior is only for compatibility with other implementations of make... you should avoid using it). Occasionally it is useful to have the same target invoke multiple commands which are defined in different parts of your makefile; you can use double-colon rules (see Double-Colon) for this.

5.4 Parallel Execution

GNU make knows how to execute several commands at once. Normally, make will execute only one command at a time, waiting for it to finish before executing the next. However, the `-j' or `--jobs' option tells make to execute many commands simultaneously.


5.5 Errors in Commands

To ignore errors in a command line, write a `-' at the beginning of the line's text (after the initial tab). The `-' is discarded before the command is passed to the shell for execution.

For example,

     clean:
-rm -f *.o

This causes rm to continue even if it is unable to remove a file.

When you run make with the `-i' or `--ignore-errors' flag, errors are ignored in all commands of all rules. A rule in the makefile for the special target .IGNORE has the same effect, if there are no prerequisites. These ways of ignoring errors are obsolete because `-' is more flexible.

When errors are to be ignored, because of either a `-' or the `-i' flag, make treats an error return just like success, except that it prints out a message that tells you the status code the command exited with, and says that the error has been ignored.

When an error happens that make has not been told to ignore, it implies that the current target cannot be correctly remade, and neither can any other that depends on it either directly or indirectly. No further commands will be executed for these targets, since their preconditions have not been achieved.

2007年3月20日星期二

How to generate a patch file in CVS?

There is one potential problem in generating a patch file from CVS repository. The RCS keyword in source files may be expanded leading to false alarm. The cvs rdiff command has an options -k to prevent this from happening, as such:

cvs -q rdiff -u -kk -ko -r rev1 -r rev2 module_name

The patch will be output to standard output. You can use your shell's redirection mechanism to generate a patch file.

2007年3月18日星期日

Website Recommendations

燃烧的烟

http://lhyong.spaces.live.com/default.aspx?_c02_owner=1

This blog space has some wonderful articles on project management related things.

折磨人的商业计划书

原文作者:Brad Feld

翻译作者:丁丁
原文链结:The Torturous World of Powerpoint

从90年代以来,我已经看了成千上万的商业计划报告。其中绝大部分都很糟糕。不幸的是,这并不是微软Powerpoint软件的错(即使 Freelance 也不能解决这个问题)。

这其实是计划书作者的责任。Edward TufteThe Visual Display of Quantitative Information 方面的权威,他认为 Powerpoint绝对是邪恶而且有害的。象 Beyond Bullets 这样的网站有助于减少这些害处,但是因为我必须在很短的时间里(通常是30到60分钟)完成非常细节内容,我想有必要更详细的介绍一下什么是“好的”计划。

几年以前,Chris Wand (他和我一起在 Mobius 投资公司工作过)列出了一些和VC商谈时必须解决的问题。如果所有创业者都自觉考虑并解答了这些问题,那事情会变得容易多了。

下面是那些应该解答的问题:

1) 你的眼光是什么?
* 你的远见是什么?
* 你要解决什么问题?对象是谁?
* 你将来想要成为什么样的人?

2) 你的市场机会是什么?市场有多大?
* 您目标的市场有多大?发展有多快?
* 这个市场有多成熟,或多不成熟?
* 你是否有资本成为这个市场前两三位?

3) 介绍你的产品和服务
* 你的产品或服务是什么?
* 解决了用户的什么问题?
* 你的产品或服务有什么特别之处?

4) 你的用户是谁?
* 谁是现在的用户?
* 谁是目标的用户?
* 理想的用户是什么样的?
* 谁会付费?
* 介绍一下某个具体用户的例子

5) 你的价值主张是什么?
* 你给用户提供了什么价值?
* 使用/买你的产品,用户的投资回收率是什么?
* 你解决了什么问题?
* 你是销售维他命,阿司匹林,还是消炎药?(奢侈品,有益的东西,还是必需品?)

6) 你如何销售?
* 销售程序是什么?周期有多长?
* 你的销售和市场方针是什么?
* 你当前的销售链是什么?

7) 你怎么吸引客户?
* 争取每个用户要花费多少钱?
* 在不同时期这个费用是否不同?为什么?
* 用户的永久价值什么?

8) 你的管理团队有谁?
* 你的管理团队有谁?
* 他们有什么经验?
* 欠缺那些环节?有什么计划去弥补?

9) 你的收入模式是什么?
* 如何赚钱
* 你的收入模式
* 需要怎样才能盈利?

10) 你现在进展到哪一步?
* 你现在进展到哪一步了?技术/产品?团队?财务/营收?
* 现在进展情况如何?现状和前景是否更清晰了?
* 你将来的计划是什么?

11) 你的融资计划是什么?
* 已经得到了什么投资?
* 希望得到多少投资?比例如何?
* 资金用在什么地方?
* 资金可以支持多久?到那时公司是否可以发展到一个重要里程碑?
* 你还打算吸引多少资金?什么时候?

12) 你的竞争对手是谁?
* 谁是你当前和潜在的竞争对手?
* 谁有可能和你竞争,谁有可能和你合作?
* 你的优势和弱点?
* 你有什么特殊之处?

13) 你有什么合作伙伴?
* 谁是你的销售或技术合作伙伴?当前?未来?
* 这些合作伙伴有多可靠?

14) 为什么适合有意的投资者?
* 和投资者的方向,经验吻合?
* 与投资者现有的投资组合有什么互补,或竞争?

15) 其它
* 成功的条件里有什么还只是假设?
* 有什么突然因素有可能一夜之间改变你的生意?新科技,新市场成员,规则法规的变化?
* 你公司的薄弱环节是什么?

===转自:http://chn.blogbeta.com/170.html===

User Interface Design For Programmers

By Joel Spolsky
Wednesday, October 24, 2001


Chapter 1: Controlling Your Environment Makes You Happy

Most of the hard core C++ programmers I know hate user interface programming. This surprises me, because I find UI programming to be quintessentially easy, straightforward, and fun.

It's easy because you usually don't need algorithms more sophisticated than how to center one rectangle in another. It's straightforward because when you make a mistake, you immediately see it and can correct it. It's fun, because the results of your work are immediately visible. You feel like you are sculpting the program directly.

I think most programmers' fear of UI programming comes from their fear of doing UI design. They think that UI design is like graphics design: the mysterious process by which creative, latte-drinking, all-dressed-in-black people with interesting piercings produce cool looking artistic stuff. Programmers see themselves as analytic, logical thinkers: strong at reasoning, weak on artistic judgment. So they think they can't do UI design.

Actually, I’ve found UI design to be quite easy and quite rational. It’s not a mysterious matter that requires a degree from an art school and a penchant for neon-purple hair. There is a rational way to think about user interfaces with some simple, logical rules that you can apply anywhere to improve the interfaces of the programs you work on.

......


This is really a nice article, check other parts at http://www.joelonsoftware.com/uibook/fog0000000249.html

Website Recommendations

ACM Queue

http://www.acmqueue.com/

This website has lots of articles introducing the current hottest topic in various aspects of computer science. I also find the issues very helpful.

2007年3月17日星期六

Note on Transactional Memory

As computer industry is transisting to the multicore world, parallel programming seems to be more and more important. What have perplexed generations of parallel programmers is the difficulty to write a parallel program. Not mention the complex lock/unlock mechanisms to protect shared datas, the released memory modeling make parallel programmers' life even harder.

To solve this big problem, and make parallel programming simpler, a new parallel expression methodology called transactional memory is proposed. TM system provide programmers with a new keyword 'atomic' to express the atomicity of a block of code. With this new keyword, advocateds of TM believe that parallel programms can be much easy to write and scale. In addition, it enables easy integration between parallel software components.

TM involves techniques from system runtime to operating system to underlying hardware. Currently there are purely software implemented TM, called STM; mostly hardware implemented TM, called HTM; hybrid software-hardware implementation, called HTM-STM; and hardware accelarate software implemented TM, called HATM.

For more details on TM, refer to http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=444&page=2

Here are my points on TM:

1) TM is essentially a new keyword 'atomic', nothing else, really!

2) With this keyword, synchronization becomes a first-class(not a library call, but at language level) concept built in in programming languages, and visible to compiler. Programmers just express what they want rather than how to do it. This way, a clear interface is formed between programmers and underlying environment. So that the environment implementation can do what ever optimizatioin they want provided not changing the program's semantic.

3) So TM is just a concept which defines the interface between programmers and system. We can expect that future programming languages provide more separation between programmers(semantic) and system(underlying implementation), so that programmers just express the semantic, and system figure out how to archieve it. This will definitely lead to various higher level constructs to appear in programming languages, rather than some lower level primitives which will force programmers figure how to archieve a specific object. We can think of pthread_mutex_lock() as a programmer-figured-out implementation of atomic keyword. Anyway, hardware are being more intelligent these days, we must tell the underlying hardware/software what we want to do, rather than tell them do this and do that to make things done, so that they can make their decisions on how to do it best. This is especially true when there are others asking the hardware for service. Think about EPIC!

4) By atomicity, what do we mean? Is it the atomicity of the execution of a block of code, or the atomicity of the access of some shared data? Obviously, it is the latter. So why do we express the atomicity of access of shared data through the atomicity of execution of a block of code? Maybe we should make the atomic keyword applied on data structures. And compilers would understand us better.

set-uid and set-gid on directories

Althrough the effect of set-user-id and set-group-id bit on files is well known to unixers, their effect on directories is not broadly understood.

In linux, you can issue 'chmod u+s item' to set the suid bit on 'item', and 'chmod g+s item' to set the sgid bit. And then, you can check the permissions using 'ls -l'. The suid/sgid bit will be displayed as a 's' on the execution bit if the item has executable permission or as a 'S' otherwise. Suid and Sgid can also set using digital form of chmod, aka, 'chmod 4xxx item' to set suid bit and 'chmod 2xxx item' to set sgid bit. In addition, you can use 'chmod [u|g]+t item' or 'chmod 1xxx' to set the sticky bit. BTW, the sticky bit of a plain file is usually ignored in modern unixes.

The effect of suid/sgid bit on directories is that the items created under these directories would be owned by the parent's owner or group owner automatically.

This is especially useful when a group of users want to share some directories with each other but not anyone else. In such a case user should set their umask to 007 and make the shared directories owned by their group and with set-group-id bit set. Example applications include cvs/svn repositories.