2008年4月7日星期一

读萨苏的相扑故事

一年多以前,在网上看到了这个故事,转自西西河:

萨苏:被外国人扫荡的日本国技 -- 大相扑

相扑这门日本人的国技,我最早见到却是在《三国演义》里面。张飞在菪渠寨大战张颌,张颌招架不住躲进寨子作抗非典状,严防死守。张飞无奈,乃放量饮酒,且在军前令小卒相扑为戏。张颌从山上看到震怒,夜袭张飞大营,被预设埋伏的张飞打得落花流水。

这里面有个问题,张颌为什么见到张飞部下小卒相扑就如此愤怒呢?我想张飞是 燕人,很可能当时河北地方在战阵上相扑,是一种侮辱对方的表现 -- 战阵上谁不是顶盔贯甲?你偏偏脱个光光的在那儿比划,整个就是嘲笑人家“军人的不是”,和诸葛亮给司马懿送旗袍一个意思。这一点别人不明白,张颌和张飞是 老乡,都是河北人,熟悉彼此的风俗习惯,当然一看就气突噜了。可见张飞并不鲁莽,很会见人下菜碟的,这 一手放到孟获身上,就未必有效,南蛮大概会以为北方人在搞同性恋游戏。从这里也许可以推测相扑这门技术出自北方的胡人,逐渐渗透到燕赵地区,游牧民族至今 多优秀的摔跤手,大概就是相扑的起源吧。

不管怎样,相扑发展到今天这个时代,它的中心转移到了善于学习的扶桑国,日 本人把相扑称为“国技”,发音为“撕猫”。经过几个世纪的轮回,在众多“小日本 儿”里面,产生了一个特殊的种群,就是“相扑力士”,这些家伙体态肥硕,在日本人中犹如鹤立鸡群,让人 怀疑不是一个人种,实际上他们不过是后天催肥的效果。相扑没有级别,自然是体重越大,越占便宜了。看到他们您可以清醒的认识到控制饮食对减肥的重要性啦, 如果您老兄红烧排骨涮羊肉的一路吃下去,体型大概也就是这个样子啦。同时,如果太太去买减肥茶,减肥霜 什么的,您也可以拿这伙儿大胖子说事儿,让她不吃冰激淋巧克力先啦 -- 不过,您这样说,被太太相扑就不是兄弟管的了啦。

言归正传,相扑力士在日本很有地位。兄弟第一次去日本,那边派了个PPMM 陪同,横滨车站上正碰上个大胖子,那MM当时就管不住自己了,一声尖叫扑过去, 又抱又亲,倾慕无比激动得不行,让兄弟看得好侧目。后来听MM讲,才知道这些相扑力士其实并不粗鲁,他 们除了相扑的职业功夫,还需要熟读诗书,大多数都可以出口成章,文化修养很高,事实上后来看到记者采访他们,也确有感受,每个力士都有相当有品位的绰号, 比如皇司,和歌乃山等,有几位力士随口就可以引用《万叶集》中的古诗表达心情,在日本人心中,相扑力士 是欧洲骑士在日本的一个变种。不过,兄弟觉得用骑士比相扑,唐吉珂德的瘦马会从坟墓里跳出来和我玩命。

日本人至今对相扑保持着浓厚的兴趣,公司之间的应酬,以赠送相扑的票为极高的礼仪,但是,八十年代后期以来,随着日本人年轻一代对传统文化的渐渐淡漠,吃苦精神的衰退,日本人对相扑,看的比练的多,日本的“撕猫”国技,也渐渐被外国人所扫荡。

日本人是个比较小气的民族,因此参加相扑比赛的外国人,也要取一个日文的名字,于是,从比赛名册上,是无从分辨他们从何而来的。但是只要看电视或看现场,就很容易发现外国的面孔越来越多。

在日本的外国相扑选手,比较有名者,前期的有小锦,曙和武藏丸,来自夏威夷,近期的则是旭天鹏,朝青龙,朝赤龙,来自蒙古,看看他们和日本本土力士的斗智斗勇,也是一个有趣的过程。

前期的小锦,曙和武藏丸,都是以体重见胜,他们都是太平洋土人的后代。玻利尼西亚土人自古以肥胖为美,练相扑可算得其所哉,其遗传决定了这些有胖底儿的家伙比日本人肥得快,结果小锦的出现,给相扑场带来一片惊呼。

第一个对日本相扑力士们构成威胁的外国人就是小锦。小锦的体重,大概是力士 中绝无仅有的,我只在电视上看过他的比赛,这家伙让日本的相扑手吃了一惊,可是 这个地震并没有太大的威胁,因为小锦身体笨重,动作迟钝,属于“虚胖”,力量和基本功都比较差,日本选 手明白过味儿来,依靠良好的技术,略施小技就弄得他在台上团团乱转,摔这大胖子就成一乐子了。

当时日本比较凶猛的选手是若乃花和贵乃花兄弟,两个人轮流作横纲老大,财源 滚滚。但是兄弟虽然兄弟,两个人的关系却势同水火,据说是贵乃花娶的老婆比较前 卫,和家里矛盾较大造成的。日本人非常喜欢这哥儿俩,因为当时鬼子的泡沫经济崩溃,很多人对社会前途失 望已极,看了这兄弟俩,便纷纷说:“看,贵乃花不是也有这样多的烦恼么?”据说对日本社会的稳定作了不少贡献。

平心而论,贵乃花在相扑场上是品德相当不错的一个选手,他动手不过为己甚, 一般来说,相扑比赛把对方摔出去以后,一个大胖子从台上滚落,四脚朝天是很耐看 的场面,而贵乃花比赛,往往只要对方出圈,还要向回拉一把,免得对手负伤。他的技术是日本传统选手的典 型,也算是把日本式相扑技术发展到了极限吧。

但是,没等日本人把“狼来了”这口气咽回肚子里,第二个和第三个夏威夷大胖子又登陆了,这就是先后在日本获得横纲称号的曙和武藏丸。

曙和武藏丸是贵乃花等日本相扑手的克星。曙,身材高大,体重仅次于小锦,他 有一套类似“推土机”的战术,根本不和对手缠斗,两臂拥住对方,利用体重一路轧 将过去,遇佛杀佛,遇鬼杀鬼;武藏丸体重稍轻(也比一般日本选手沉得多),但是比较灵活,很有力量。在 这两尊巨灵神的得打击下,日本相扑选手传统的技术无法应对,土崩瓦解,简直不堪一击。贵乃花在连连失利以后,决定退役,他老爹当年也是相扑好手,痛斥他缺 乏斗志。贵乃花把武藏丸的手印拓下来给老爹看,一只手掌就比自己的脸还大,这个仗怎么打?贵老爹看了以 后,长叹无语。

这两个夏威夷胖子横行相扑界达数年之久,其间,耻于日本选手的失利,贵乃花曾经再次下场夺回横纲,那打的真是太苦了,在最后一战中贵乃花竟然把超级大胖子武藏丸拔萝卜一样举了起来,真是玩老命了。

但这也不过是昙花一现,总的来说,老一代日本相扑手对于曙和武藏丸,总是象大砖头一样碰的一声撞上去再弹回来,始终没有好的应对办法。

日本人的小气此时暴露出来,各种报纸上,充满了对于两个夏威夷大胖子的不屑,纷纷表示这种靠体重取胜的比赛丧失了相扑的魅力 -- 相扑本来就是大胖子的运动,日本人一直也没有认为它失去魅力,只不过现在鬼子胖不过夏威夷人,嘴巴里酸酸的说。

正在此时,一个奇特的日本选手琴光喜出现了,这小子出道较晚,水平一般,但 是对曙或者武藏丸却十战九胜,战绩辉煌,人称“巨人杀手”,颇有一种“内战外 行,外战内行”的感觉。究其原因,琴光喜专门对两个巨人进行过研究,比赛中脚步十分灵活,每战不和对方硬 顶,不断改变自己方位,使对手无法锁定目标,然后挑巨人脚步移动的一瞬间出击,造成巨人失控,这样“四两拨千斤”的功夫中国武术早有研究,但日本武术刀法 都走刚猛一路,缺乏弹性,琴光喜的打法可算一革命性的变革。记得当时每次把曙或者武藏丸摔倒,观众席上 都是座垫纷飞 -- 日本人用这种奇特的做法表达自己的喜悦。

琴光喜本人并没有当上横纲,他在对低重量的日本本土选手时往往战绩不佳,也 算一物降一物。然而他带动了一批诸如栎东,雅山等日本选手如法炮制,夏威夷大胖 子的时代,开始没落了。这期间的相扑台上,常常看到一个小个子逗着一个大个子团团乱转的场面。曙大概是 在受不了这种转木马游戏,不久被查出患有疾病,他每次比赛无论胜败,只不到一分钟的战斗就会大汗如雨,最后退出比赛;武藏丸也被打到了练门,成绩每况愈 下,直至被勒令退役。

表面上,日本人夺回了相扑的统治权,然而,水面下的暗流正在越来越汹涌。

这道暗流就是蒙古相扑选手的崛起。

蒙古选手在日本相扑界的加盟,最早的应属现在依然十分活跃的旭鹫山,不过他 原来在蒙古摔跤界的地位一般,到日本后主要也是采取增加体重的打法,虽然有一定 的成绩,仍然被视为战绩平平。只不过是带来了“蒙古人也能相扑”的印象。和他同时进入相扑的,还有一个 小个子朝青龙,今天成了日本相扑界的霸主。

朝青龙刚刚在日本相扑界露面的时候,兄弟并没看好他。因为他的身材矮小,技术粗糙,只记得每战必以双手猛击对手两侧面颊,如打耳光般啪啪作响,到把对手打昏为止,场面颇为尴尬。谁知道2002年以后,此君在相扑台上掀起了一股蒙古旋风。

2002年,曙,贵乃花等都退役了,琴光喜武藏丸状态不佳,山中无老虎,猴 子称大王,朝青龙忽然发威,一举拿下横纲之位,震惊四方。2003年继续连霸, 而且居然取得了33连胜的惊人战绩,是日本平成年代最长的连胜记录,堪称打遍天下无敌手。他的弟弟朝赤 龙也登陆日本,一出手就获得12连胜,日本选手望风披靡!

开始,大家还认为他是侥幸取胜,等看过他的比赛,才明白,他给日本相扑界带来了一个恐怖的挑战 -- 这位兄弟把蒙古摔跤带进了相扑台。假如相扑真的起源于古代胡人,这下子朝青龙把它返朴归真了。

那位说了,相扑不也是摔跤么?和蒙古摔跤有什么区别呢?这里面有区别的,可以说,是从朝青龙兄弟开始,相扑选手才发现自己还长着肘关节和膝关节的。

传统的相扑,象牛的格斗,主要靠体重,讲究的技术是全身整体的发力,上肢用 力重上臂,把对方提起来或甩出,下肢用力主要在屁股,利用扭腰的力量把对方放 倒,所以称为力士,传统日本人的相扑选手,手肘和膝盖关节,基本上是固定不变的。而朝青龙兄弟一改力士的 传统形象,他们的身材不高,体重也很一般,但是身体肌肉发达,尤其是小臂,小腿的动作变化无方,利用膝,肘拐弯的欺骗性招数带动对方重心,即便是逆境中, 也常通过挤,靠,叼,拿等蒙古摔跤的动作突出奇兵,而令对方猝不及防,好似碰上了欧阳锋的灵蛇拳。

比如朝青龙对日本选手中身材最为高大的魁皇,扭住对方手臂,膝盖半弯作绊,只一个回合就力擒对方于马下。魁皇相貌英武,在日本选手中胜率很高,赛前双方都以为会是一场恶战,实战表明缺乏变化的日本相扑手在虚虚实实的蒙古摔跤面前无论身子还是脑子都不够使。

当然,把蒙古摔跤揉进相扑,朝青龙兄弟动了不少脑筋,使其动作适应相扑的规 则,而其小巧灵活的招法,又富于观赏性。尽管朝青龙近日失利了一次,从场面看属 于轻敌失误,一交手就被对方从上方压住,未及施展手段就落败,真正从技术上击败朝青龙兄弟,日本相扑手 还没有什么办法。

值得一提的是面对朝青龙兄弟的成功,日本的舆论虽然也责怪过朝青龙比较傲慢,但远比对曙或者武藏丸宽容,这大概是面对小个子输得比较心服,同时日本人一向认为自己是蒙古人东渡的后裔,被蒙古选手占了上风不觉得很丢人吧。

最近,看报纸,又有新的外国人选手出现了,其中,有保加利亚来的,还有中国来的,他们又会给相扑台带来怎样的变化呢?让我们拭目以待。

山雨欲来风满楼阿。

以上这篇文章让我看得很纳闷,因为,从头至尾,几乎没有符合事实的地方。居然也可以侃上这么一大篇。

从头说起,相扑的起源居然从三国演义里推想,也太过荒唐,有人认为起源于汉朝军队中的军体术,倒是一说,但相扑在日本已经有一千多年的历史,至少要比三国演义成书的时间早吧。

力士的称号叫四股名,并不是有品位的绰号,而是作为力士身份使用的艺名,有的是传统继承的名字,可以由他们自己和师父商量决定,比如迄今为止就有三代若乃 花。所以外国力士起日文名字也不能得出日本人小气的结论,还有力士叫“琴欧洲”(因为他出身保加利亚,“琴”是他师父一门的常用字),“战斗龙”(因为出 身美国St. Louis),一眼就能看出是外国力士。

在日本有名的外国相扑选手,早在小锦来到日本的20多年前就有一个叫高見山大五郎的夏威夷人,英文原名James。在60年代作为外国人第一次在最高级别 的幕内比赛中取得优胜,最厉害时做到关胁(从上往下数第3级),而且迄今仍保持着幕内出场比赛的纪录:1430场。他才是第一个对日本相扑力士们构成威胁 的外国人。当年他还是曾经是貴ノ花(横纲貴乃花的父亲)的克星,也是日后第一个外国人横纲曙的师父。一个有趣的插曲,高見山追着貴ノ花,一不小心自己摔了 一跤,结果输了(相扑中谁先摔倒就输),是相扑史上罕见的镜头。

小锦有过辉煌的时候,他才来日本的时候一口气做到大关(从上往下数第2级),优胜后没有给他升横纲,还抱怨说是受到种族歧视。他厉害时,连当时的横纲都被 他4把推到台下。但此后他无法控制自己体重,导致行动迟缓,反应迟钝,走上了下坡路。(萨苏看到的可能是他选手生涯晚年的情形吧)

大概说一下相扑的系统:相扑中最高级比赛是幕内级,力士排行从前头十四或十五排到前头一,然后是小结,关胁,大关,最后是横纲。除了横纲外,其他的地位都 不是固定的,如果一场锦标赛共15战中输了8场以上,地位就要下跌,只有最高级别的横纲是终身的,但如果成绩不好就必须引退。因此也没有“轮流作横纲老大 ”“夺回横纲”一说的。

若贵二兄弟关系不好,不是因为他们的妻子,相反地,贵乃花的妻子河野景子比他大7岁,原来是演艺界的,婚后甘心做家庭主妇,并不前卫。两兄弟关系不好的真正原因有二:

1,他们父母之间的关系不好,后来离婚。争执过程中,哥哥若乃花站在母亲这边,而贵乃花站在父亲这边。

2,若乃花怕吃苦,不愿意继承相扑的家业(传统是长子继承),而贵乃花正好相反,而且从相扑的实力上来说,他也看不起他哥哥。

日本人喜欢这兄弟俩,是在他们翻脸之前,因为他们从小就出名,很多人几乎就等于是看着他们长大的。

若乃花和贵乃花兄弟和曙,武藏丸基本上是同期入门。贵乃花(当时贵花田)最早优胜,当时17岁。他把千代的富士打败,促使他引退(千代的富士当年打败他父 亲,促使他引退),算是报了家仇。这四个人中,最早升大关,横纲的都是曙,也因为他,贵乃花一直做不到横纲。(因为升横纲的基本要求是做了大关后连续两次 优胜,而每次在贵优胜后肯定是曙扳 回一次,所以贵在优胜7次后也没有升,十分稀奇)但曙也一直有个遗憾:没有全胜优胜过(15战全胜),每 次也是最后一战输给贵,所以他们两个人应该是势均力敌。(这四个人中最早是武藏丸全胜优胜。)所以原文中若贵二兄弟先有优势之类的,是完全没有根据的。

曙的特点是手长腿长(他原来想做职业篮球手的),所以凭借身体优势卡着对手的喉咙(叫喉轮,突手) 推,左右开弓,几下对手已经飞了出去,十分威猛。对手因为没他手长,所以根本无法近身;而他的弱点正是近身肉搏,因 为重心高,容易被摔倒受伤。从这里也可以知道萨苏根本没看过曙的相扑。

我很钦佩曙,这是因为当年比赛时,若贵兄弟一门中师兄弟众多,而且相互间不可以对战,所以他们优胜得容易,而曙却是要对付众多高手,曾创下一次锦标赛中打败3个横纲4个大关的纪录。

曙最辉煌的时刻应该是在和若贵兄弟三人最终决赛中连胜两兄弟而优胜。但后来也是遇上了控制体重的问题,使膝盖负担过重出问题,成绩下降,才使贵乃花有机会 连续优胜做 到横纲,并称霸了一段时间;但贵乃花为了打败曙,也付出了沉重的代价。他选择了增加体重,才能和曙抗衡,结果导致内脏机能出问题,导致过早结束运动生 涯。

若乃花却是在曙身体不佳,又不用和贵对战,以两次极差的优胜成绩爬到横纲,但这也不幸导致他不久被迫引退。因为他是技巧型的力士,所以对战时经常避免正面 交锋,而是使用各种技巧。可是横纲的崇高地位要求他正面对敌,贵乃花对曙或小锦这类巨人也是硬碰硬,并不退缩的。这对于若乃花来说,是要求过高了。于是他 在力不从心,在创下一连串作为横纲的不名誉丢脸的纪录后引退。武藏丸则是大器晚成,在以上三人都临近退役后,靠身体壮实,终于熬出头做到横纲。

“座垫纷飞”是相扑观战的规矩,横纲输掉后观众必做的事,与歧视无关。

以上种种,可见萨苏一文实在是吹得太多,只凭道听途说就能洋洋洒洒一大篇,也太不像话了。萨苏能侃,而且是那种能够引人入胜式的侃法。听他的首都机场,西 北军等的故事,都觉得有趣,佩服他居然有这么丰富的阅历和经历。但看了这篇文章,不由得使我开始怀疑起他以前别的文章的真实程度了。

介绍英特尔的优化库IPP(下)

有了(上)的基础,可以谈一下深一步的内容了。使用IPP函数,程序或者使用动态库连接,或者是静态库连接。

使用动态库的场合,需要在IPP安装目录stublib下的库,如ippi.lib。这时执行程序本身不大,但需要IPP的DLL,它们一般是在IPP安装目录bin下,名字为ippi.dll等,还有和平台相关的DLL,稍后会详细解释。

使用静态库的情况,要使用IPP安装目录lib下的库,如ippimerged.lib。这样生成的程序比较大,因为含有所有执行平台的模块,好处是不再需要IPP的DLL了。

使用动态静态库的问题,是C语言的常识,这里不多加讨论。需要解释一下IPP的工作原理。

[更多:]


看IPP安装目录bin下有个文件叫libguide40.dll,这是判断计算机CPU类型的,从而决定调用哪个对应平台的DLL。比如,bin下的ippi.dll其实只是个接口,真正的功能是靠以下4个DLL之一实现的:ippipx.dll,ippia6.dll,ippiw7.dll,ippit7.dll。(最新版5.1的文件命名方式略有变化,版本号也被使用,成了ippi-5.1.dll)

以上的px,a6,w7,t7实际上指定了应用平台。据英特尔称,px用于一般的芯片,a6用于奔腾3的芯片,w7用于普通的奔腾4芯片,而t7用于新的Prescott核心的奔4。对于其对手AMD的芯片,则一律认定是普通的芯片px,不给与特殊优化。

但AMD芯片的用户就只能用普通IPP功能了吗?同样的问题在一些嵌入式系统的用户中也有,因为这些系统的芯片也会声称和英特尔芯片兼容。再仔细考察IPP的原理,可以发现,还是有办法强迫IPP对非英特尔芯片进行优化的。

其实所有IPP函数都是裸函数,全部由汇编写成,C语言的函数定义不过是提供了接口而已。这样对用户的好处是用同一代码可以得到不同平台的优化。以上的px/a6/w7/t7实际上和英特尔的指令集合有关系:

t7对应了SSE3。
w7对应了SSE2。
a6对应了SSE。
px就是普通的MMX。

所以根据你手头的CPU是否对应以上的指令集,可以通过这样的方法来使用IPP的优化。要注意的是程序调用必须以__stdcall 的方式,也就是编译器用/Gz为选项。以下的代码可以加入在(上)中的例子:

#include
#ifdef IPPAPI
#undef IPPAPI
#endif

#ifndef IppiAxis
typedef enum {
ippAxsHorizontal,
ippAxsVertical,
ippAxsBoth
} IppiAxis;
#endif

extern "C"
{
#define IPPAPI(type,name,arg) extern type px_##name arg;
static type (*d##name) arg = px_##name;
__declspec(naked) type name arg { __asm {jmp d##name } }
IPPAPI(void, ippiFree, (void* ptr))
IPPAPI(Ipp8u*, ippiMalloc_8u_C1, (int widthPixels, int heightPixels, int* pStepBytes))
IPPAPI(IppStatus, ippiMirror_8u_C3IR, (Ipp8u* pSrcDst, int srcDstStep, IppiSize roiSize, IppiAxis flip))
}


这里需要对原来的ippMalloc/ippFree的两行换成:
data = (Ipp8u *)ippiMalloc_8u_C1((int)szFile, 1, &lineStep);

ippiFree(data);
可以根据需要将代码中的px换成a6/w7/t7等。

因为有这样方便的机制,才使得我们可以在源代码不改的情况下也能获得Intel新平台的优化。

介绍英特尔的优化库IPP(上)

英特尔不仅在硬件开发上独占鳌头,在与硬件结合的软件上也有相当的实力,更是其死对头AMD所望尘莫及的。著名的软件有英特尔的C/C++语言编译器,以及系列优化库软件。这里谈一下优化库IPP。

IPP全名是Integrated Performance Primitives,有个中文译名,叫英特尔® 群集工具集, 名字颇为拗口,但其功能非常直接:提供程序处理中的优化功能。编程的时候,如果在一些很关键且耗用CPU的处理中进行优化处理,可以大幅度提高程序性能和 缩短执行时间。这些优化,除了对程序进行合理安排之外,就得使用一些高性能的汇编指令了。不过这么一来,程序变得复杂,而且难以维护,还有就是不同的 CPU(甚至包括尚未出现的)的对应也会成问题。对此,英特尔的IPP给出了比较完善的回答。

[更多:]


IPP可以从英特尔网站下载。其Linux版本是免费的,而Windows版可以免费得到评估版,如果你要使用Windows版作商业用途,则应该付199美元。

这里简单介绍一下IPP的用法。刚打开一个IPP的头文件,会觉得里面的函数名如同天书一般的复杂。其实根据其文档看,名字还是有规律的。

一般的IPP函数名如下:

ipp<data-domain><name>_<datatype>[_<descriptor>](<arguments> ) ;

这里的data-domain所谓的域,指的是该IPP函数所属的功能范围。s(signals)代表一维的信号处理;i(images/video)代表二维图像处理;m(matrices)代表矩阵处理。

datatype数据类型的定义是位数加上位解释组成。位数有<1|8|16|32|64>,位解释则有[c]。

这里u是无符号,s是有符号,f是浮点数,c是复数。

descriptor是描述符,描述要操作的数据。
A表示数据有Alpha色。
C加数字n表明图像数据有几个颜色频道,1|2|3|4。
I表示操作仅在此数据内存的范围内进行,不需要多余的内存空间。
R表示需要指定ROI即圈选范围。

以此来看最常用的申请内存的函数ippiMalloc。由开头的ippi可以知道这是用于二维图像的,所以需要指定宽和高,还有一个用于返回逐行字节长度的指针。

Ipp* ippiMalloc_(int widthPixels, int heightPixels, int* pStepBytes);

看说明它有以下这些修饰符:
8u_C1 16u_C1 16s_C1 32s_C1 32f_C1 32sc_C1 32fc_C1
8u_C2 16u_C2 16s_C2 32s_C2 32f_C2 32sc_C2 32fc_C2
8u_C3 16u_C3 16s_C3 32s_C3 32f_C3 32sc_C3 32fc_C3
8u_C4 16u_C4 16s_C4 32s_C4 32f_C4 32sc_C4 32fc_C4
8u_AC4 16u_AC4 16s_AC4 32s_AC4 32f_AC4 32sc_AC4 32fc_AC4


因此就可以根据自己的不同需要来调用不同的ippiMalloc函数了。

最后给一个小例子。

HANDLE hFile;
DWORD szFile, dwBytes;
Ipp8u *bmpData, *data;

hFile = CreateFile("TEST.BMP", GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open file (error %d)n", GetLastError());
return;
}
szFile = GetFileSize(hFile, NULL);
data = (Ipp8u *)ippMalloc((int)szFile);
ReadFile(hFile, data, szFile, &dwBytes, NULL);
CloseHandle(hFile);

IppiSize iSize;
BITMAPINFOHEADER *header;
int lineStep;

header = (BITMAPINFOHEADER *)(data + sizeof(BITMAPFILEHEADER));
bmpData = data + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
iSize.width = header->biWidth;
iSize.height = header->biHeight;
lineStep = ((header->biWidth * 24 + 31) / 32) * 4;
ippiMirror_8u_C3IR(bmpData, lineStep, iSize, ippAxsHorizontal);

hFile = CreateFile("TEST1.BMP", GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open file (error %d)n", GetLastError());
ippFree(data);
return;
}
WriteFile(hFile, data, szFile, &dwBytes, NULL);
CloseHandle(hFile);

ippFree(data);


这是段完整的程序,它所做的是读入一个RGB24位的BMP文件TEST.BMP,然后将图像进行水平翻转,写到一个叫TEST1.BMP的文件里。(这 里故意使用Win32的文件处理函数,喜欢Unix风格的就自己修改吧)用到的IPP函数是ippiMalloc,ippFree, ippiMirror_8u_C3IR。

Intel还是AMD,这是个问题

个人计算机(PC)的中央处理器(CPU)只有两大主流:Intel和AMD。它们之间的恩怨情仇,可以写一部小说了。

Intel和AMD分别成立于1968和1969年,不过AMD直到1975年才开始进入处理器市场,还是推出了通过逆向工程克隆的Intel的8080 处理器。八十年代初,IBM推出PC,采用Intel的芯片为CPU。可是,如同一个国家政府般庞大的IBM内部有条政策:采用的芯片至少要有两家供应 商。于是,Intel和AMD在1982年2月签订协议,AMD成为Intel的后备,同样可以生产8086/8088的芯片。AMD也基于同一协议,生 产了286芯片。但Intel在1986年推出386芯片的时候取消了这个协议,为此AMD把Intel送上了法庭。经过漫长的诉讼,1991年法庭判决 Intel应向AMD赔偿10亿美元,但AMD也从此不得使用Intel的芯片技术,可谓是两败俱伤。

可能两者都意识到了这点吧,此后它们达成新的协议,内容保密,AMD此后却可以合法使用Intel的技术,而且很长时间里没有新的诉讼。它们的和解只害了 一个人:Guillermo Gaede。这老兄先后受雇于AMD和Intel,但他在Intel干活的时候录下了技术资料寄给AMD,正逢上两家和解,结果马上被AMD出卖,被判入 狱。

不过AMD一路走来,颇为辛酸。它克隆Intel的386和486芯片的时候都因为要模仿对方技术,而CPU技术更新周期越来越短,往往是它才完成了克 隆,这技术就过期要被淘汰了,所以结果都很惨。同时,Intel推出奔腾芯片后,不再使用586为编号,而声称奔腾是商标,不像以前什么86那样可以让 AMD使用。于是AMD不得不决定:独立自主,自力更生。1995年终于推出了独自设计的K5芯片(这个K代表了Kryptonite,是漫画书中唯一能 使超人受伤的物质,超人是谁,自然大家心里有数),功能介于586和686之间,不过由于种种先天不足,在性能上还是无法和Intel随后推出的奔腾II 抗衡,可以说是完全失败了。

1996年,AMD买下了由前Intel的雇员们开办的NexGen公司,并给于他们最大的开发研究的自由,不予干涉。这才诞生了K6芯片,而且经过不断 努力,到了1999年第三代K6芯片问世时,已经在速度上赶上了Intel。但K6潜力趋于终结,99年8月,前DEC公司Alpha芯片的开发者领导 K5和K6的开发小组,推出了K7芯片,也就是Athlon。Athlon以高钟频著称,迫使当时因步步领先而疏于更新的Intel不得不重新设计P6的 核心,从而引发了一场看谁先达到1GHz钟频的竞赛,结果是AMD赢得了这场竞赛,而Intel则是第一次认识到自己一向看不起的对手终于拥有向自己挑战 的实力了。作为对策,Intel一方面声称AMD的高频芯片并不能代表高性能,另一方面却推出了以高频为卖点的奔腾4代。

Intel凭借生产技术上的优势,奔腾4代钟频从1.6GHz开始,轻松跨过了2G,3G的门槛,而且也早已把4G,5G放在了计划里,却没有意识到奔4 的成功也同样是致命性失败的地方。AMD一开始也被奔4的高频打闷了,因为用户选择CPU倾向于看钟频数字越大越好,AMD的低频使得销量一落千丈。这时 AMD作出了明智的决定:不和Intel竞争高频,而是分析Intel奔4的弱点,同时开发K8芯片。奔4芯片的高频的代价是沉重的:执行效率低,以至于 不得不引入超线程(HT)来补偿不能完全发挥的高频优势;耗电量大,以至于计算机厂家对此怨声载道。如同美国汽车的引擎。而AMD适时推出了K8芯片,虽 然钟频上无法和奔4抗衡,但却用了新的编号系统,比如真实钟频为1.8GHz的却编号为3000,意思是功能和奔4的3GHz芯片旗鼓相当。这得到追求高 性能的用户的承认,在商业上也获得了成功:普通用户开始意识到,Intel的奔4是高频低效。而且,K8的在32位处理器上的64位寻址功能(被称为 AMD64)也获得了微软的认可,并且迫使Intel在奔4的新核心里也必须加入同样的功能。这对Intel是前所未有的羞辱:不得不采用自己从不放在眼 里的对手的技术。K8也凭借设计上的优势,挑战Intel,将双核心技术作为新的战场。

Intel面对对手的挑战,也作出了明智的决定:马上终止奔4核心芯片的开发,修改摩尔定律的方向。摩尔定律是Intel创始人之一的摩尔在1965年时提出的:集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,性能也将提升一倍,而价格下降一半。 以前,Intel是把提高钟频当作提升性能,而现在则是把其他的性能诸如执行效率,耗电功率以及集成核心数目都算在内。但由此而产生的问题是:芯片的钟频 不再上升,以前预定出品的4GHz芯片也取消,只能依靠增大芯片内的缓存容量,追加新的技术,如64位寻址,虚拟控制,双核心等来作为卖点。一时间,同样 钟频为3GHz的奔4芯片出了近十种,孰优孰劣,把用户都快弄糊涂了。无奈之下,Intel只得取消芯片钟频的标记,而采用编号制,如同高档汽车的编号一 样,用3位编号的芯片,第一位是档次,比如5xx和6xx的区分,这里以6开始的要比5开始的高一个档次;第二位表示钟频的快慢;第三位是一些附加信息。 今年开始,Intel还要引入4位编号的芯片,这样做的好处之一就是使得AMD的编号芯片失去比较对象。

经过一年多的动荡,Intel终于设计出新一代的芯片,定名为“Intel Core”,定于7月投入市场。这代“核心”芯片,继承了以色列工程师设计的用于便携式电脑用的芯片的风格,以耗电低,钟频低但执行效率极高为卖点。目前 已知的情况是:同样的钟频,新核心的芯片性能比AMD的要高出10~20%。而明年年初,4核心的芯片也要登场。在这一波波Intel的攻势下,看AMD 如何作出反应,也是件有趣的事。

Intel,还是AMD,对于广大电脑用户来说,这是个值得 高兴的烦恼。因为他们之间的不断竞争给用户带来了好处:现在的电脑,性能越来越好,而价格却越来越便宜。不过对我而言,还没有把选择Intel还是AMD 当作一个问题,而总是选择Intel。因为Intel不仅拥有强大的硬件开发技术,软件开发也很优越,特别是它提供的一系列基于Intel芯片的优化软件 运行库,对开发图像处理的程序员来说,是必不可少的。AMD在这方面的差距还很大。

企鹅一家

世界真奇妙(如姜昆杨澜般展开单臂)!看这企鹅一家,多可爱。


想把看到的景象保留下来,自然的想到用相机,保存到电脑里。可是以前的电脑太旧,不能显示彩色,它只知道黑或白,非黑即白。结果变成这样:



有人生气了,说:这是假的,要纠正过来。但如何纠正,是个问题。把黑白颠倒过来就行了吗?



其实就算只用黑与白,还是可以想办法逼近真是的,比如:



虽然和真实相比差了不少,但已比上面两个有了进步,虽然还是非黑即白的只有两种颜色。

如何改进呢?自然是用更多的颜色来表现。如果不用彩色,只把全黑到全白分256个层次,可以得到灰度图,用来再现照片的结果,是这样的:



这才是平时所说的黑白照,黑白照并不是非黑即白,而是用灰度表现。

再进一步则是用红绿蓝来再现了。和灰度类似,人们把红绿蓝三原色各自按256分阶段然后组合起来,就可以表现256x256x256即超过一千六百万以上的颜色了。不知道人眼是否能识别所有的颜色,但用红绿蓝基本上可以忠实再现自然了。本文开始的图片正是这样的结果。

于是我们就再也不用灰度了吗?不是。现在的数码相机非常普及,感光部分差不多都用的是CCD(charged coupled device),中文译成电子耦合组件。CCD感光后记录下颜色,然后可以输出。如果用3原色,自然需要3个CCD,这样一来成本会升高。所以一般只用1个CCD。1个CCD怎么能表现出彩色?这里要用到Bayer颜色了。

Bayer颜色是一律用灰度表示彩色。但按照特殊矩阵的位置决定当前的灰度是三原色中的哪一个。一般的色彩矩阵如下:



这里可以看到绿色用得比较多,这是因为人眼对绿色比较敏感的关系。经过Bayer转换后的图像如下:



从这幅灰度图可以还原出以下的图像:



怎么样?还不错吧。大多数使用数码相机的就是这个效果。

我们已经看到了如何利用有限的资源做尽可能多的再现真实世界,也知道因为人的视力的局限,事实上很多从灰度转换来的彩色已经足够让肉眼满意了。

无论如何,让红绿蓝三原色各有256个层次看来是最高目标了,现在大多数显示器都可以满足这个要求。但这是不是最终目标呢?请看下图:



看上去和开始的那幅彩色图没有区别,但实际上这图里的红绿蓝每个原色都有65536个层次,所以包含了比256个层次更多的信息。这些信息,在目前的显示 器上没有很大用处,但在计算机图像处理上却是越来越重要。因为人们可以用这么多信息来做更多的事,如局部放大,加亮,变暗,更自由的变换。

依次类推,技术可以无限的发展,从而更接近于真实世界。

恐龙级程序员的编程技巧

前些天接到用户电邮,抱怨我们公司的软件所产生的C语言代码无法编译使用。看了一下他提供的出错信息,居然是说CrtMain的入口找不到。这不禁让我觉 得好笑,因为我所参与开发的这个软件的确有产生代码的功能,但只是一个函数的代码,而不是整个可执行的程序,没有C语言所必需的main()函数,怎么可 以执行?看这位用户的名字,应该也是身在海外的华人。我因为本身交友圈子的局限,认为现在在海外的中国人都是会编程的,如同以前中国人靠3把刀谋生一样。 将这个当笑话讲给同事听,不料,同事却说:这说明你已经成了恐龙了,现在谁还会用C语言编程?java,.Net的程序员才不会在乎这个main呢。这让 我笑不出来了。

我开始工作时开发平台是Sun4(那时SPARC工作站还没有问世)+C语言(C++也根本没有成熟),写程序用的是vi(这我倒是一直使用到现在,成了 gvim)编辑器,老前辈说:这还算好的,要知道以前的ed,只能编辑一行啊。颇有些忆苦思甜的味道。调试环境只有一个终端可以输入命令,虽说程序出错后 会有Core被吐出来,但只有牛人看得懂这个Core里有什么东西,我可没有到这个级别。所以只有狂加打印语句,看程序在什么地方死掉。用标准输入输出出 错的方式,以及怎样连接各条命令,让他们管道相通,还有如何用tee只截取出错打印的信息等等。但有时候打印也不行,因为加了几句打印会使得原来出错的地 方消失,只好再猜测到底哪里可能出错。

时过境迁,在微软几乎一统天下的情况下不得不在Windows上编程。一下子还真适应不过来:远程窗口执行没有了,远程终端不行,窗口的程序打印语句看不 到。但程序员就是只有使用可以使用的工具的命,多年下来,居然也习惯了微软的一套规矩,终于把Win32 SDK编程学会了。可是,还是不断的有新的技术语言出现,这些新概念如此之多以至于要让我放弃去学习新知识的努力,学会用大胡子同事的怀疑眼光看待一切新 事物:所谓新技术只是那些大公司的阴谋,来折腾我们这些被划入恐龙级别的程序员的。

的确,当时用UNIX的时候学到那些老的编程哲学,要简洁明快,尽量让别人看不懂。这倒也迫使我学会了不少技巧和冷门知识,如使用awk,yacc, lex,makefile等。但到了现在,都成了过时的东西,看来早晚C程序员要被微软逼迫关到管理内存空间里去。不过微软很多地方是借鉴了UNIX,但 就是不将这些技巧写入文档,方便大家使用。我在工作空闲的时候(比如等待编译完成),在网上搜索,找到了一些我认为有用,但却是没有人在乎的小技巧。事实 上我也不常使用,不过为了避免遗忘,还是记下来的好。

比如,在窗口应用程序中使用打印语句,有如下的办法:

只要在程序初始化时加入:
AllocConsole();
freopen("CONOUT$", "wb", stdout);

然后可以写一句试试:
printf("TEST n " ) ;

别忘了结束时的处理:
fclose(stdout);
FreeConsole();

就这么简单。

游戏人生

我年轻时一度沉迷于电视游戏中,用当地的说法是在游戏中燃烧青春。游戏种类有很多种,我最喜欢的是对战格斗和RPG(角色扮演)两种。

对战格斗,顾名思义,便是两个角色对战,因为游戏设计者将所有心血化在设计对战的两个角色上,同时也最充分的应用了该游戏机硬件的性能,自然是最精彩的 了。以前读的武侠小说与之相比,就未免缺乏身临其境的格斗感觉了。屏幕上,只有你和对手的两个角色,要在一分钟里决出胜负,将对方打倒。你能做到的,是用 手上的操纵杆控制你方的角色做出各种动作来,移动,进攻,防御。摇杆和按键的组合则可以出招,所谓的必杀技。等到角色的体力不支的时候,便可以使出威力更 大的超必杀技,往往可以一击必杀,反败为胜。所以即使到了即将获胜的时候也不能掉以轻心,因为对方随时可能放手一搏。超必杀技的命令组合,更难轻易使出, 我为了练习这些招数,手上还磨出了老茧。

玩这种格斗游戏,一般不会超过半小时,因为这实在需要精神高度集中,注视游戏画面的所有变化,一点疏忽就可能一败涂地。但作为忙碌工作后的精神调剂,还是可以的。而且能够使出超必杀技来打败对手,更是一种享受。

RPG游戏,则和格斗游戏完全相反,不需要很紧张,但却很花时间。RPG是Role Playing Game的简称,即角色扮演。一般是你控制主人公在虚拟世界里冒险。主人公会从一个没钱没本事的小毛孩,历尽各种考验,积累财富,学会本领,成长起来,完 成重大使命。在这过程中,会遇到各种人物,结交朋友,聚散分离,走出自己的小村子,到大城市,飘扬过海,到别的大陆,经历不断的丰富,拥有更多的资本和实 力。

RPG游戏的想法简单,但成功的并不多。《最终幻想》和《勇者斗恶龙》是最出名的两个。这两个游戏在哪个游戏机平台开发,也决定了游戏机厂商的兴衰。为什 么它们会受欢迎?我想,关键是游戏规则和情节安排。游戏规则一定要简单明快,使玩家容易上手,但情节安排一定要变幻莫测,使玩家总能够有兴趣玩下去。西方 的一些经典RPG游戏太难,总是猜不出其中的谜语,又或者是敌人太强,无法过关。而太过简单的游戏又太容易打完,觉得枯燥无味。所以如何在调整其中的平 衡,是需要很好的技巧的。

有时候会不由得将RPG游戏和人生联系起来。每一个新的游戏就是一个新的人生体验。和真正人生不同的是,游戏还可以推倒重来,也可以设置一个还原点,尝试 一下别的可能性。精彩的游戏让你沉迷其中,但对于平庸的游戏你还可以选择:不玩了。不过,玩游戏多了,有时候确实难以分别:什么是游戏的世界?什么是现实 的世界?