Aug 23

本次更新的主要内容包括:

  1. 加入了关闭/打开内模糊切分的选项
  2. 加入了使用backspace取消用户选择的选项
  3. 升级系统词库和语言模型至open-gram 0.1.22
  4. 解决了Sparkle升级时无法打开安装包的问题
  5. 加入了小鹤双拼方案的支持
  6. bugfixes若干

功能方面和上次在twitter上放出的RC版本,没有什么不同,主要是将数据文件更新至了open-gram 0.1.22。虽然Sparkle升级时无法打开安装包的问题已经解决,但是得等到下一次更新的时候才能起作用;所以,烦请大家不要通过自动升级来安装,而是直接下载pkg包来安装 …

欢迎大家下载试用

Tagged with:
Jul 16

首先请下载这个导入工具,解压缩到某个目录中。从pinyin.sogou.com下载细胞词库(scel格式),保存在某个目录中。然后在terminal中执行下面的操作:

$ python import_sogou_celldict.py <path to your cell_dict.scel>

感谢中文社区其他开发者和项目reverse engineering的工作,

Tagged with:
Jun 20

This is my reading notes of “Concurrent Programming on Windows”, as I said before, I am quite a newbie on this area, there maybe errors in my understanding and summary, please kindly point them out if there is any.

Tagged with:
Jun 04

tbb::concurrent_vector

stl::vector相比,tbb::concurrent_vector不支持inserterase操作,且不保证内存是连续的。因为不支持insert操作,故而无法实现由一个线程进行插入排序,并同时由另一个线程去遍历的场景。TBB中也没有平衡树的支持,估计是因为,插入/删除时的节点移动操作很多,细粒度锁不容易带来更佳性能的原因。

template<typename T, class A>
class concurrent_vector: protected internal::allocator_base<T, A>,
                         private internal::concurrent_vector_base;

typedef concurrent_vector_base_v3 concurrent_vector_base;
// VC10 defines its own v4 template

struct concurrent_vector_base_v3::segment_t {
void* array;
};

atomic<segment_t*> my_segment;
segment_t my_storage[pointers_per_short_table];
// pointers_per_short_table = 3

concurrent_vector_base_v3::concurrent_vector_base_v3():

将指针数组my_storage的元素赋值为NULL, 然后将my_storage赋值给my_segment。

concurrent_vector_base_v3::segment_index_of(index):

即 log2(index|1)

concurrent_vector_base_v3::segment_base (k):

(1 << k & ~1),和2**k(即1<<k)不同,当k为0时,结果为0而不是1

concurrent_vector_base_v3::segment_base_index_of(index):

将index调整为segment内的索引,并返回是第几个segment。

concurrent_vector_base_v3::segment_size(k):

返回第k个segment的大小。1 << k,k==0时应该返回2才对呀

从逻辑上看,concurrent_vector内部的segments布局如下,总会是2,2,4,8,16,32…

但是实际分配的空间,则可能是16,16,32,64,取决于第一次的reservation, growth 或 assignment操作。如果第一次要求分配10个元素,那么heap上分配的空间是,比10大的最小的2的幂数,即16。

(插图来自http://blogs.msdn.com/b/nativeconcurrency,VC10中的concurrent_vector和TBB中的是同出一脉的。)

concurrent_vector::push_back (item)

调用internal_push_back(sizeof(T), k)去分配一段空间,然后调用internal_loop_guide(ntrails为1)将item拷贝到分配的空间上,最后返回iterator

concurrent_vector_base_v3::internal_push_back(element_size, &index)

使用__TBB_FetchAndIncrementWacquire将m_early_size加1,并将原来的size赋值给tmp和index。调用helper::extend_table_if_necessary(*this, k_old, tmp),在必要时扩展segment table,调用helper::acquire_segment获取一个segment的基地址,计算偏移并返回对应的地址。

libittnotify是一些profiling的函数,在编译时可以打开或关闭。ITT=>Intel Threading Tools。

Tagged with:
Jun 03

非常灰常抱歉,昨天(06/02)发布的2.0.2中发现有一个crash的bug,感谢@fishwang同学的bug report。我刚刚fix了这个bug(#134),并上传了最新的2.0.2的完整安装包,原链接不变。烦请您重新下载安装,对给您带来的不便,实在是万分抱歉 :(

Tagged with:
Jun 02

本次更新主要是对2.0.2-beta-1进行了一些修正,加入了“声母简写(z/c/s->zh/ch/sh)”的选项,也加入了全角空格的支持(尚未支持全角小写字母)。

从2.0.2开始,SunPinyin 2 for Mac 全面采用了open-gram的词库和语言模型,因此会导致您的history cache无效,您可以在执行完安装程序之后,手工删除现有的history cache文件($ rm ~/Library/Application\ Support/SunPinyin/history)。另外一个重大的更改是,扩大了wordID的范围,使系统词库+用户词库的理论容量可以达到2^24,您现在可以放心导入比较大的个人词库了。不过这也导致了和2.0/2.0.1的词库格式不相兼容。

正是由于上面两个原因,2.0.2的安装包中,直接包括了lm_sc.t3g.le和pydict_sc.bin.le的二进制数据文件,大家可以直接安装就好。另外,sunpinyin_importer中的系统词表也更新为open-gram的词表了。

对于power的mac用户来说,我们已经解决了大端数据的生成问题,请在安装时下载相应的数据文件 … 另外,非常抱歉的是,sparkle自动升级的问题还没有来得及解决,请大家不要通过自动升级来安装,而是直接下载pkg包来安装

欢迎大家下载试用

Tagged with:
May 27

http://club.blogbeta.com/2010/05/13-sunpinyin

时间:2010年6月4日星期五晚上,19: 00开始
地点:奇遇花园咖啡馆(问路电话010-88320741)
地址:西直门北展北街9号华远企业号(华远地产)D座一层(地图

演讲题目:What’s new of SunPinyin 2.0

内容预览:

演讲人简介:
孙勇,SunPinyin项目的Lead Engineer之一,SunPinyin Mac Porting的主要维护者。
个人blog,http://yongsun.me,twitter: @yongsun

参与说明:无需报名,参加免费,点单AA

Tagged with:
May 27

因为工作的关系,现在对C++的并发编程十分有兴趣,TBB无疑是这一领域的佼佼者。我主要对并发容器、scalable allocator比较有兴趣。现在刚刚开始读TBB的代码,这里是一些粗浅的笔记,欢迎大家多指正 …

tbb::machine

tbb_machine.h中引入了所有支持平台的头文件,如果对应平台没有定义__TBB_CompareAndSwap4,__TBB_CompareAndSwap8,__TBB_Yield,或__TBB_release_consistency_helpler,就会报错,无法支持。如果没有定义__TBB_load_with_acquire或__TBB_store_with_release,就会通过__TBB_release_consistency_helpler来实现它们;如果没有实现__TBB_Pause,就通过__TBB_Yield来实现。

__TBB_rel_acq_fence和__TBB_release_consistency_helper不同,前者是一个真正的硬件的fence,后者只是为了告诉编译器不要进行重排。Intel的编译器就将__TBB_release_consistency_helper定义为空了,但是GCC需要特殊的定义。但是奇怪的是,MSDN上说_ReadWriteBarrier是包括硬件fence的。

内存语义(memory semantics):

load_with_acquire: 栅栏之后的内存操作不能移动到load之前;
store_with_release: 栅栏之前的内存操作不能移动到store之后;

__TBB_machine_fetchadd1等方法,通常定义在src/<arch>/atomic_support.asm中的,ibm_aix51中是一个C文件。

某些term和Windows API的对应关系:

fetch-and-add => InterlockedExchangeAdd
fetch-and-store => InterlockedExchange
compare-and-swap => InterlockedCompareExchange

atomic_backoff: pause()方法,在前5以内,是指数级的backoff,之后调用__TBB_Yield()来交出CPU。bounded_pause()会在5次尝试之后,返回false。

还定义了原子的OR和AND操作,以及__TBB_TryLockByte,__TBB_LockByte等辅助函数(都是基于CAS来实现的)。

tbb::atomic

enum memory_semantics: {__TBB_full_fence, acquire, release};

后面两个应该只是为支持IA64的,只有在linux_ia64.h中定义了__TBB_DECL_FENCED_ATOMICS这个宏,并实现了型如__TBB_CompareAndSwap##S##M(其中S是size,M是memory_semantic,例如__TBB_CompareAndSwap4acquire)等方法。如果这些方法没有被定义的话,tbb_machine.h中会用__TBB_full_fence语义的版本重定义之。

atomic_rep: 对长度为[2, 4, 8]字节的类型,都要求对齐;即加入了一些编译器属性。

template struct atomic_traits;
包括compare_and_swap, fetch_and_add, fetch_and_store等几个基本的方法。

atomic_impl实际上是对atomic_rep和atomic_traits的一个包装。而atomic模板从atomic_impl中派生得到的,对指针类型来说,是从atomic_impl_with_arithmetic中派生的(void *除外),以对指针的移动操作(例如++, –)进行memory barrier的保护。而atomic_impl_with_arithmetic也是从atomic_impl中派生的。相比atomic_impl,atomic对赋值操作operator=加入了fence的保护。

tbb::blocked_range

包括1维、2维、3维的实现。模板参数是iterator类型。表示一个半闭半开的区间,[my_begin, my_end)。当区间的size<=my_grainsize时,区间就不可再分了。其中一个构造函数,可以将当前的range(*this)分为两半,新构造的range是后一半,旧的range被修改为前一半。

Tagged with:
May 27

跟随老婆单位同事组织的黄山游,4天3夜,加来去两晚的卧铺。

周五夜里的火车,硬卧上铺,空调风力太足,吹得我头痛不已。龟缩在被子里,蒙头浅睡了一夜。周六早起到合肥,有小雨,很冷。用罢早餐,乘事先联络好的旅游巴士,出合肥奔黄山方向。至汤口用午饭,然后驱车到西递参观。西递的很多牌楼和古籍,在文革时被破坏的很严重 … 傍晚到宏村入住在农家,吃农家菜。住宿条件很幽静,有热水可洗澡 …

第二天早起参观宏村,已经有了在西递屋檐累累的熏染,宏村的阁楼不再那么令人兴奋,但风景仍然十分迷人。

短短2小时之后,乘车去黄山。至黄山,乘中转巴士,到紫光阁。我们这一队老弱病残的同学,坐缆车上山。然后循大众路线至白云宾馆入住。中途路过迎客松,有点失望。且山中雾气弥漫,只偶尔露了几片蓝天。不过宾馆的条件比预期好得多。夜里各路人马汇合于宾馆,研讨分组路线,我和老婆第二天去挑战一个比较有难度的路线。晚上观摩了两局三国杀 …

第三天经光明顶,去北海看云海。8点钟至光明顶时,远眺云海很是壮观。遗憾的是,约1小时后,到达最佳观赏地,猴子观海时,已经消散了大半,很是遗憾。然后经排云亭,下西海大峡谷。经过4个小时的停停走走,终于回到了白云宾馆。因体力不支,没有继续随队去丹霞峰去看日落。晚上玩了两把三国杀。和另一队人马,相约隔天早起去看日出 …

第四天3:45起床,4点多一些到达光明顶时,观赏日出的各个据点已经人满为患了。辗转爬上悬崖边上的一大块岩石,脚下即是深渊。我爬上去之后,本已显得拥挤的岩顶,陆续又爬上来4个人,其中包括3位女士和一个老外。大家为了拍摄日出,真的是置生死于度外了。本来还想再去北海看云海,不过从光明顶看过去,当天是不会有云海现身了。于是回宾馆睡了个回笼觉。早上9点多和老婆再次经光明顶,至云古索道下山。中午随便在景区外吃了点饭,然后回合肥。到合肥吃了顿丰盛的晚饭,然后乘夜里的火车返京。

第五天早起到京,回到家洗了个澡,然后就去单位上班了 …

Tagged with:
May 14

2003年10月8日,国庆节后的第一个工作日,我来Sun中国工程研究院的北京国际化中心报到。我至今仍然十分感激当时的老板Scott,记得当初他面试我的时候,问我如果加入Sun有什么职业上的规划,我回答说“听闻Sun公司内部有transfer制度,员工可以在工作一定时间之后选择其他方向发展,如果有机会,我希望一两年后能transfer到浏览器组去做开发”。很感谢Scott,在听到我这么“二”的回答之后,还是给了我机会。

到Sun之后,第一个项目是接手Evolution的本地化和国际化,作为Evolution l10n/i18n项目的central engineer,要参与各种的项目会议,这对我来说的确是一个很大的挑战。我当初英文很差(当然现在也不好),很不习惯在电话里听别人说英文,口语的表达能力也很差。着实适应了一段时间。l10n/i18n的bug fixes有的可以很简单,有的则需要深入到程序内部,特别是有很多和输入、输出、DnD相关的问题,通常都很棘手。后来工作范围也扩展到了gnome上的l10n/i18n。为了管理测试用例和记录测试结果,学用Struts写了套很简陋的测试用例管理系统,不过因为其他site已经有同事写了一套类似的系统,而遭废弃。

04年6月份,有机会和同事(Gavin)到美国rotation两个月。我第一次坐飞机就是10多个小时的长途飞行,结果到了旧金山后发现无人接机。后来发现是同事把时差搞错了,告诉美国同事的接机时间,是当地的第二天。我们只好自己准备摸到公司租的公寓去。一路上先是坐Bart,然后坐Caltrain,好像当天Caltrain还因为是什么节日而免费,然后坐light-rail,最后坐bus,终于到了公寓附近。然后给国内的同事打电话,争取联系到接机的同事,恰好这位同事周末在单位加班,否则我们只有去办公室睡沙发了。我和Gavin都是穷苦孩子,过的很节省,都是自己做饭。一天两顿饭,晚上做好的菜,拨出一半留着明天中午带饭吃。两个月1000美元的补助(房租是公司付的),我买了100多美元的书,100多美元的化妆品(给老婆的),还老人家带了若干维生素,最后回国的时候,还剩了80美元的现金。美国的同事打趣说,500美元一个月的补助还是多了…

那段时间,我的同事张磊博士在独立开发一个基于统计语言模型的输入法,也就是今天的SunPinyin。我一下子就着了迷,找了很多NLP相关的论文和书来看。憧憬着有一天能够投入到这个输入法的开发中。后来,因为要弄一些自动测试的东西,又学了些shell脚本,还学了些python,以及pyrex,给python写扩展。业余时间,也翻译(或合译)了一些书,包括《Struts KickStart》,《Mastering JavaServer Faces》,《Agile Java》,《Programming Ruby》等一些技术书籍,对基于Web的企业应用开发也很有兴趣。我的一个最大的缺点就是兴趣太广,泛而不精。有时我很苦恼,有时又乐在其中,没办法了…

后来,Sun逐步削减了在JDS-Linux上的投入,将JDS上的一些开发都转移到Solaris上。我们和日本的一些同事,要负责将IIIMF的新版本(R12),从linux移植回solaris上。我还负责了简体中文、繁体中文、以及欧洲compose输入法的维护工作。这期间还代表公司参与了亚洲输入法标准的讨论和制定工作,结识了CJK许多输入法的开发者,例如James Su、Huang Peng、Wu Peng等等。我为日系和中系两路人马的沟通和交流做了一点点贡献。因为日本方面的主要负责人,Hideki Hiura,曾经是我们国际化部门的资深架构师,他是XIM协议的提出者之一,openi18n.org社区的奠基者。不幸的是,前不久得到他的噩耗,因病逝世了:( 同志们都要注意身体啊…

这个标准工作组最后同意开发一个全新的输入法平台,即imbus。但是由于种种原因,始终停滞不前。后来,我和Huang Peng一起提出了用python+dbus实现输入法平台的初步构想,也就是今天的iBus。很遗憾,我只是提了一个构想,贡献过一些很high-level的design,并没有贡献过什么代码。

后来,张磊同学去我们的宿敌M$做Bing去了 :) 便将SunPinyin的开发和维护工作转交给了我。随着OpenSolaris的开源计划,SunPinyin也一并以CDDL协议开放给了社区。为了吸引更多的开发者加入我们,我写了一系列的blog,介绍SunPinyin内部的实现细节。我的blog也因而经常出现在blogs.sun.com访问量的前60名(尾部)。也因为在博客上的交流,结识了tchaik0v同学。他很热心的帮助我们将SunPinyin从IIIMF移植到了SCIM平台上,现在仍然是SunPinyin社区中最主力的开发人员之一。为了让Linux各发行版能更好的接纳SunPinyin,我又建议和推动了将SunPinyin改为CDDL+LGPLv2的双授权协议(这一协议也沿用至今)。

后来迷上了Apple,买了台MBP。MacOS自带的拼音输入法着实很难用。QIM是收费软件,FIT虽然免费,但也不是很满意,就想能不能把SunPinyin移植到Mac上。随着Leopard的发布,基于IMKit框架开发输入法变得比较轻便和容易了。我花了四天三晚,照着苹果官方的例子,对着obj-c/cocoa的简明教程,将SunPinyin初步移植到了Leopard上。很感谢我的老板,允许我干这么一件看起来和Sun的业务毫无关系的事情。实际上,我们的这个移植还是非常划算的。Mac的用户都是一群完美主义者,给我们提了大量的意见和建议,极大地鞭策和促进了SunPinyin的继续发展。我也因此结识了jjgodLin Zhemingchumsdock等许多好朋友。

因为SunPinyin-1.0架构上的一些局限,要实现一些新特性很困难,因此我就开始了2.0版本的开发。在开发过程中,也把同事Xue Wei给involve进来,帮助我实现了双拼切分和用户词典的功能。直到这时,我仍然时不时地需要去fix一些IIIMF的bug;有时还要做很多RE(Releasing Engineer)的工作;还有其他一些小的项目。这些琐碎的工作有时真得让我感到很沮丧。后来同事帮我做了一个统计,我在Sun的这近6年时间里,周均要fix 1.5个bug,大概是我们北京国际化中心这边入职时间相当的工程师里,最多的一个。

08年的金融危机,成了压在Sun身上的最后一根稻草。Sun被Oracle以74亿美金收购了。一轮又一轮的裁员,部门里的人事和结构的不断变更,HR的一些“作为”,以及对并购后工作方向上的不确定性,让我渐渐有了离开的念头。后来,汤森路透这边有一个机会,是用C++开发高并发的金融应用。我对并发编程一直很有兴趣,虽然很犹豫,最后还是接受了offer。我的老板和二线老板都希望我能留下来,至少等收购完成看一看再说。我的老板们对我都很nice,一直很支持我,如果还没有签offer,我想我真的会选择留下来…

无论从哪方面讲,Sun都是一家伟大的公司,公司的文化非常宽松和开放,给员工的自由度非常大,也非常鼓励员工的创新。我们部门可以全周在家办公,只需要周四到单位碰个面;不定期的有knowledge sharing的session,这个session可以讲任何大家有兴趣的topic,甚至包括摄影、装修、理财等和工作毫无关系的内容。这些都让我们部门成为一个充满家庭般温暖的、紧密团结的大家庭。如果不是因为收购的问题,我真的希望自己能在Sun做到退休…

2009年8月20日,在美国政府批准Oracle收购案的前一天,我从公司离职了。而到今天为止,Sun中国工程研究院还没有合并到Oracle中国研发部门。我所在的那个组,曾经10来个人的team,走得只剩下两个人了…

在Sun的近6年岁月里,我获益良多,这是我从业以来最开心的日子,我将永远铭记在心…

preload preload preload