Becomin' Charles

算法 | LNMP | Flutter | Mac

Becomin' Charles

真是无比惭愧啊,过了这么久,连这么基础的知识都不知道,特意记录在此。

今天,实验室要求我编写一个小程序,操纵一个摄像头按照指定的时间间隔拍摄照片。真的是小Case啦。两个多小时,我做完了。晚上,我兴致勃勃的开始了测试。

按照需求,我测了一下1秒中内等时间间隔拍摄10张图片。在反复不断测试中,我突然惊讶的发现了一个问题——我拍摄下来的图片,不是间隔100毫秒的,而是间隔109毫秒。

开始,我以为这是因为我的中断处理程序的执行时间造成的,于是,我给时间间隔做了个修正,即如果设置时间间隔为100的话,在程序内部,就按照90毫秒来触发。发现这种情况下,时间间隔变成了93或94毫秒。

终于还是把这个问题问出了口,对面的小哥立刻告诉我,Timer使用的时间中断,Windows中每隔1/18秒触发一个时钟中断,所以,Timer的定时精度只能达到55毫秒。晕死,这么简单的事情,我竟然不知道,一看msdn,还真是这么回事。

按照msdn的指引,选用了所谓的更加精确的服务器计时器,System.Timers.Timer,重新测试,发现结果没有变。晕死,怎么会这样呢?仔细看文档,对比.net framework中拥有的三种定时器。Win32定时器,服务器定时器,线程定时器。Win32定时器是单线程定时器,精度55毫秒;服务器定时器是多线程定时器,其精度可能比Win32定时器精确得多(注意只是可能);线程计时器专门用于那种消息不在线程上发送的解决方案,没有提到其精度。原来如此啊。

对于最终的结果,我有如下的结论:
1、我用任何定时方法,都无法达到指定的精度,其原因可能与码流本身有关,因为我调用的是第三方非开源的控件提供的ImageCaptur方法,该方法截取图片的时间间隔可能受到帧率的影响,而我除了使用这个非开源控件,不能用其他办法操纵摄像头。
2、虽然说Win32定时器(System.Windows.Forms.Timer)的精度只有55毫秒,但是实际使用中,发现产生的最终结果和System.Timers.Timer相同,即,不是93或94毫秒,就是109毫秒。由于我对msdn更加信任一点,所以这个结果就更加使我确信,实际拍摄的时间间隔受到视频流本身的帧率的影响。
3、实际上,可以更加进一步地调查定时不精确的原因,并且寻求解决办法(最终结论可能还是没有解决办法),但是由于这个选择的性价比实在太低,不值得尝试,所以,到此为止。

这部片子,在豆瓣上的评价还是挺高的,绝大多数人给了3或者4星。不过,我的评价还只能是just so so啦(其实因为别的评价我不会用英语表达,说笑啦(当然也可能是真的))。

因为要写这个影评,所以,我搞清楚一件事情,就是那个老头叫做乔治·克鲁尼。对有些人来说,可能真的是大牌吧,但对我来说只是个“脸儿熟”(我印象比较深的是十二罗汉有这个老小子)。要说这哥们演技好吧,好在哪里呢?长相好?眼光比较深邃。表情好?大部分时间,他的脸都没有什么丰富的表情。对白好?一般啦,真没看出来哪里好。其实,这个老小子一直都有一种赖赖的表情,尤其是影片结尾的时候,有一丝丝的洋洋得意,有一丝丝的轻蔑,有一丝丝的微笑,有一丝丝的痛苦。这么看来,还是演技有点好的哦。

然后说说这个故事情节,就是一个“这个社会很黑暗”的故事。真的是很普通啦,国内这种故事也多了去了,一公司,生产了有毒化学品,然后死扛,错上加错,最终颠覆的故事(最好每家这样的公司都颠覆了,但是这只是没好理想,实际上,绝大多数都是扛得住的,受害的都是我们这些小老百姓,所以,千万别乱吃东西,别生病)。在这么个故事里,乔治同学是一个良心泯灭的“看门人”,专门给各个烂摊子擦屁股的那种人,生活在舞台之下的阴影里面。终于他的好朋友亚瑟也搞了个烂摊子,他是那个混蛋公司的辩护律师,但是竟然向有毒物质受害者倒戈了(良知被唤醒,虽然之前泯灭了12年)。没啥悬念,亚瑟同学死了。迈克尔(乔治同学)当然比较好奇,没想到,好奇心会害死猫,杀猫人来了,迈克尔侥幸逃过一次暗杀,奋起反击,取得了最后胜利(奋起反击这一段,基本也就5分钟的戏份)。

让我一顺叙,好像就没啥悬念了吧,导演又是将剧情搞个颠三倒四,所以悬念了。当然,这个比起李安的《色戒》,真是小巫见大巫,悬念得不厉害的。所以,综上,我就觉得只能给个just so so了。

阅读全文 »

今天换成杭州卡,收到了一个短信,发现漫游费终于下调了。

怎么说,以前到底漫游费有多高,我是不是很清楚的,只是知道,贵得很离谱,到什么程度,就是像我这样的一般一个月不超过40手机费的,一次旅游了3天回来,当月手机费接近100了。明白了吧。漫游费的计算方法只有运营商才有权利解释,往往是长途费用加上漫游费用,简直贵得难以忍受。

现在杭州移动的漫游费标准是主叫6毛,被叫4毛。当然,在我看来,这个还是很贵的。而且,这个费用也没有说清楚是否还要叠加长途费用。

按照我原来的理论,这个费用本质上下降是不可能的。因为这个关系到一个各方利益的问题。因为如果漫游费很低廉,甚至取消了,那么就可能使得手机用户全部集中到手机话费最低廉的地区去,这个绝对不是运营商希望看到的。为了维护住让手机资费偏高地区的用户不要流失,才出现了漫游费这么莫名其妙的东西,这个几乎不要需要成本的一个东西,竟然成了翘首费用,按地区分赃的一个分界线了。

说白了,就是一家移动,一家联通,一家电信,大家都是国有企业,手心手背都是肉,按照地区来划分中国大蛋糕,相当公平,漫游费也就不可能取消,除非出现真正竞争性的对手,否则,中国手机费,只能是永远居高不下。

其实,我的一些列理论未必站得住脚,但是事实是可以说话的。技术上,谁先进我们不比较,但是国外的电信成本比中国低,那是不容置疑的。我的朋友会打越洋电话跟我煲粥,而这对中国人来说,是向都不敢想的。想想那可怕的电话费吧。

这两天,我很不理智的花了5块钱。

前天,我从杭州回家,在地铁上看到一个乞丐,我想起来我自己也想扮乞丐要饭的,就多打量了两眼,结果,这就犯错误了,找上我了,颤抖着手,在我面前,叮铃,叮铃。我突然很有负罪感,很快就掏了一块钱给那人。

完了,我就后悔了,我又把一个人向堕落的深渊推了一把。一个手脚完好的中年人,干什么不能挣口饭吃呢?偏偏干这个,这么没有尊严。而且,我给的这一块钱,只是在那一瞬间,满足了我泛滥一下同情心的小小欲望,对于他们这一类人来说,绝对不会带来本质的帮助。给他们钱,就好像,你缴费来满足一下同情别人的感觉一样。

紧接着又来了个女的,牵着一个唱歌的盲人孩子,我赶快扭过身去。生怕自己再向一个已经堕落的身躯推出致命的一掌。

话说,我今天又干了个蠢事。又是从地铁出来,我突然被一个女人叫住了,长得金鱼眼,可吓人呢。脚像桩子一样钉在地上,然后身子探过来跟我说话,扭扭捏捏的,然后我当然没听清,后来重复了一便,我还是没有听清楚,就搞清楚一个,她要钱,而且是3、4块钱,因为她连回家的钱也没有,我正在想事情,就头昏脑胀的又同情泛滥了一回,给了她4块钱,她说谢谢,真是太谢谢了,就转身走了。

完了我,超级后悔,怎么会相信她的话啊,太好骗了吧。当然我也不确定她是个骗子。但是我想起来,正直的人,一定不会像她那么目光闪烁,而且说话还遮嘴,还含糊不清。一般来说,应该是让我写下一个地址,把钱寄还给我吧,怎么就白要了呢?怎么就这么好意思呢?这不就变成乞丐了吗?

而且,我还没有主动帮助她把这看成是借,她搞不好会想,我竟然沦落到需要讨饭回家,真丢面子啥啥的,根本不会感慨这个世界还是好人多。唉,犯错误了~~

我是一只小蜜蜂,飞到西又飞到东,嗡嗡嗡嗡嗡嗡嗡嗡,不怕雨也不怕风~~

看了了这个电影,我不由得想起来以前真的很喜欢这么一部动画片的,现在只记得主题曲的这么两句词了,嘿嘿。这部电影,真的,说什么好,真的让我对老美的想象力表示折服。蜂巢内部,纷繁复杂,却又井然有序,实在令人叹服。

感觉上,这部电影四处弥漫着老美那独特的个人主义思潮,四处都透露出一股弘扬个人主义的味道。作为一只最最普通的工蜂,原本被安排的命运就是在一个普通岗位上工作到死,但是Berry根本就对此等安排充满了怀疑。这种怀疑成为了他探索世界最强大的动力,以至于后来捅了一系列娄子,搞得世界天翻地覆。

剧情不想多讲,最后,一切终于又重归与正常,但是并非意味着集体主义,安分守己,战胜了个人主义,而是个人主义真正的胜利,世界不但重归于秩序,而且全部是按照主人公向往希望的那样去运转了。这部电影把个人主观能动对世界带来的影响夸大了极致,可以说是一部极度褒奖个人英雄主义的电影。

有的时候,真的不得不惊叹老美的单纯,如果你有一个美国同学,你一定会感叹,ta是多么地单纯可爱,至少我是这么觉得的。无论是电视剧,电影,动画片,都准确无误地给我传达了这样的思想,每个美国人都能自得其所,根本没有必要思考更多的问题,所以,经常的,你就会觉得他们真的是傻的可爱。我甚至觉得,美国人民,是世界上最容易愚弄的人民,我在这里做个大胆的假设,大部分美国人民心中攻打伊拉克的理由和bush政府是根本不一致的,明白了吧,这就是神奇之处。

扯远了,回到电影上,这部电影还是很不错的,你可以感叹一下那些惊人的想象力,可以感受一下超越了种族的烂漫情怀,你可以感受到商业大片的紧张刺激,你可以感受到完美地个人英雄主义,你当然还可以看到很多美国式的幽默,然后就是一个happy ending啦~~

阅读全文 »

已经有两类基于在覆盖图内部(intra-overlay)优化的方法被提出了,基于树状的覆盖图(tree-based overlay)和基于网状的覆盖图(mesh-based overlay)。尽管原有的组播方法得到了优化,但是仍旧困扰于较长的延迟和突然的中断,尤其是当大量的peer同时加入网络的时候(为什么这个时候会有突然的中断?)。

所以呢,基于覆盖图与覆盖图之间(inter-overlay)的优化算法被提出了。这种算法的主要思想是:不但要像早先的算法那样利用一个overlay中的网络和计算资源,但是还要利用不同的overlay中的节点的计算资源。好像记得一篇文章中提过这样的事情,就是一个正在看CNN的用户,其有宽裕的带宽资源,所以他会替一个正在收看BBC的用户转发视频流中的包。通过这样的方法可以更大限度的使用网络的带宽,均衡网络的数据流。使用户具有更好的使用体验。

接下来,我们来描述一下AnySee的工作方式,第一步,建立一个高效的,基于网状的覆盖图(使用了基于位置探测器的算法来匹配物理层的拓扑,啥意思?这里有个关键组件忘了提了,mesh-based overlay manager);第二步,单覆盖图管理器(single overlay manager关键组件之一)(利用传统的覆盖图内部的优化算法)来处理加入和离开覆盖图的节点;第三步,覆盖图间优化管理器(inter-overlay optimization manager又一个关键组件)探索合适路径,建立备份连接(backup links),裁剪QoS比较低的分支;第四步,关键节点管理器(key node manager)分配有限的资源,缓冲管理器(buffer manager)管理和调度视频数据的传输。

在AnySee中,每个节点首先要加入到基于网状的覆盖图中,每个节点都有一个标识符,该节点首先连接初始节点,然后挑选一个或者几个节点来建立逻辑连接。每个节点维护一组逻辑邻居。这个步骤的关键就是要让基于网状的覆盖图于网络节点的物理拓扑相匹配。这个mesh-based overlay manager使用一种叫做LTM(Location-aware Topoloy Matching)的技术来优化覆盖图,找到最近的邻居避免慢速的连接。主要使用两种方法flooding-based detection with limited TTL和updating logic connections。这两种算法我也没有看得太过明白,我这里就先不展开了。

接下去是Single Overlay Manager,这个组件主要是用来管理peer的加入和离开操作的。在覆盖图之间的优化开始之前,一个peer首先加入一个覆盖图,至于是接受来自于一个节点还是多个节点的数据,是取决于单覆盖图优化的结果的。在这个设计中,引入了一个新的属性,叫做LastDelay,意思就是说,从当前这个节点通过每一条去达源节点的路径中,产生的最小的那个延迟。(不过,关于这个延迟怎么计算,论文里说得很不清楚,这让我也比较疑惑)

一般来说,每个节点维护一个活跃流路径集和一个备份流路径集。最初,所有的流路径都是由Single Overlay Manager来管理的。当备份流路径小于最初的数值的时候,覆盖图间优化算法被启动了,用以在全局范围内找到一个合适的流路径。当一个活跃的流路径由于比较差的QoS或者某个节点的离开而被剪掉的时候,一个新的流路径会从备份流路径中选择出来。这也就是说,一开始,一个覆盖图还仅仅涉及到一个源,如果某条路径的断裂,或者QoS小于某个值了,将会导致发起全局范围的路径探索,最终促成了全局范围的优化。这一段后面很详细的阐述了这个算法,我现在实在是没有勇气在这里来描述,先放着。

然后我简单描述一下关键节点管理器,这个东西的作用就是帮助管理富余的资源的,还是,我掠过算法不讲,只讲思想,首先这个组件将所有的富余的资源管理起来假如有N个,然后将向本节点发起的请求也管理起来,将他们排入M个队列,然后将富余的资源逐一分配给请求队列,分配的过程遵循一些算法。

最后,缓冲区管理器用来管理收到的和发送出去的数据包,这里使用的算法和CoolStreaming里面的算法是一致的,但是由于CoolStreaming里面没有使用覆盖图之间的优化算法,为了降低延迟,其缓冲区设计得都比较大,也就意味着较高的播放延迟,而在AnySee中,这个缓冲区就可以设置得比较小,相应的在播放延迟的问题上,将要获得更好的性能。

IP层的协议是按照最小化功能的原则来设计的,只提供了最大努力(best-effort)单播(Unicast)数据报服务,而剩下的包括流控制,差错控制等一系列的功能,都扔给了终端(End System)去实现。

这种设计理念正是Internet能够长足发展的一个非常重要的技术层面的原因(到底为什么呢?)。Internet的长足发展,又刺激了大批应用的开发,而大批应用的出现,又对Internet的基础功能,有了更高的需求。

那么到底应该在IP层提供什么样的更进一步的服务呢?组播(Multicast)和QoS正是正在或者已经加入到IP层协议中的两个特性。QoS单单通过终端系统,是无法实现的,与此不同的是,组播完全可以通过终端来实现。

那么组播到底放在哪里呢?首先回顾End-to-end Arguments(这是啥玩意儿?)的两个原则:
1、功能尽可能放到上层实现
2、除非下层在复杂性上做出牺牲可以换来巨大的性能提升,否则不在下层实现功能。

Deering1989认为,他出于以上第二个准则考虑后,认为组播应该放到IP层实现,而且很多人认为这是对的。但是实际上,IP组播,有很多弊端,首先路由必须维护每个组的状态(为什么啊?),这违背了“无状态”架构设计准则,而且增加了复杂性,降低了扩展性(how?)。IP层协议原本是最大努力单播协议,在其上实现高级功能非产困难(为啥?)。基于以上原因,IP组播没有大规模发展起来。

所以呢,Yang-hua Chu等哥们儿提出了终端系统组播(End System Multicast)。简单来说,就是把组播的实现上推到了终端,在IP层仅仅依赖单播(复杂了咋说呢?)。所谓的Narada Protocol就是实现该一思想的一个协议(终于进入正题了)。

其实,在Narada协议中,还没有明确提出过P2P的概念,但是为什么称其为P2P呢,我想原因大概是这样的,P2P顾名思义,就是平等的意思,大家都是一个Peer,功能上基本相似的(其实不完全一样,对于视频流协议来说,也不可能,因为必然有一个视频源,怎么可能和别的Peer对等呢,但是除了源与众不同以外,其它的节点应该都是平等的才对),那么终端组播的思想,其实就是将高级功能分配到每个终端,以此来实现组播,这么看来,每个终端就像是一个Peer一样,由此,Narada协议是一个P2P的协议。

昨天,一直看到很晚,虽然有一肚子的问题没有搞懂,但是还是让我挡不住地认为,这个协议蛮鹾的。首先,我来回忆一下Narada的拓扑结构,说白了这个Narada也是要构建覆盖图(Overlay,真是搞不懂这个东西)的,只不过是树状的覆盖图,其构建网络的过程是,先构造一个富连接图,称之为网(mesh),当然,这个图不是胡乱构建的,要满足一些性能上的指标才行,具体的,我想是视实际应用的网络而定的,比如根据网络延迟和节点距离来决定两个节点之间是否构造一条边等,接着,在这个网上,构造生成树集合,每棵生成树都以视频源为根(注意,该协议一开始就假设有多个视频源存在,对于单一的视频源也是可以适用的,但是其可靠性,就会下降)。

在Narada协议中,突然就提出了组(group)的概念,但是没有为其下明确的定义,我想,应该可以理解成上文提到的整个网的生成树吧。为了分散由单一节点管理整个组的信息的风险,组的信息管理和维护被分散到了每一个节点(P2P的思想,但是在这个协议中,真的不是分散啊,而是每个节点维护全部的组员的信息,所以说它鹾啊)。为了获知每个节点的活跃与否,组的每个成员(Member)被要求按照一定的周期向外发送一个唯一序列号,该序列号沿着整个网络传播(高冗余)。这样,每个组员至少要维护这么几个信息,每个组员的地址,组员i上回发来的串号k,接收到串号k的时间t。可以想见,如果一个节点发现某个节点超过一定的时间(Tm)没有发来串号,那么那个节点肯定有问题了,这个时候,一般启动恢复机制(实际上,由于网络的延迟,对于每一个节点来说,传播串号的时间是不一样的,所以,一个节点,相对于每个节点的超时时间Tm是不一样的,这也是应该维护的信息啊,但是文章中没有指出这一细节,我想,我的猜测还是合理的,因为串号沿着整个网络传播,如果一个节点真的失效,那么所有节点都会发觉有节点失效,按照协议,所有节点都启动恢复机制,对于一个死掉的节点,竟然有n-1个恢复连接请求在网上传播,真的是太鹾了)。如果恢复失败,就宣告死亡,每个组成员还要保留一个成员的死亡信息足够长时间。

上面说得比较顺,就先讲了这个节点脱离的处理机制,下面来讲讲,入伙的机制,这个其实比较简单的,说白了,就是傻等,首先获取一份组员列表(论文没有详细说怎么获取,向谁获取,不过,我想这个很简单的吧,因为每个组员都有完整的一个列表的),像列表中挑选出来的几个发送入伙请求(怎么挑呢?),然后傻等,加不断重试,直到入伙成功后,开始接受所有其他组员的信息并且自己也开始发送信息。

上面一系列的机制有个说法的,叫什么被动检测,主动测量(passive monitor,active mesurement)。我好像还没有看出active在什么地方,以后还需要好好咀嚼。

然后讲讲数据流的传输,流主要是沿着生成树来传播的,有个算法叫做反向最短路径算法,复述一下那个例子,如果M通过N接受S的源的话,那么当且仅当N是从M到S的必经的最近的路径时,N才向M转发数据。(这里还有一些东西要看的。感觉自己的语言好乏力,理论基础也太过薄弱了。)

Narada协议的适用范围是非常小的。这倒是不难理解,那么冗余的结构,每个节点保存全部其他节点的信息,可以想见,规模扩大后会发生什么,对此,此协议作者倒是相当诚实,他认为这个协议适用范围在几十到数百的组规模的应用。并给出了试验数据来说明。

这些天,我经常用定时发布的功能,主要是为了好玩,发现定时发布的文章,有时候不能正确统计其数字。

今天我在Archive页面,发现3月份发表了26篇文章。而所有的分类里面的文章数量竟然只有23。那么还有3篇文章哪里去了呢?

原来是定时发布的文章,没有被分类统计进去。比如,我好几天前发了一篇文章,讲键盘的,被归到了“趣闻”一类,但是我在分类管理面看到,趣闻一类里的文章数是0,我打开那篇文章,然后直接按保存,再看,发现数字被更新了。这样我就找回了丢失的3篇文章。

顺着这个思路思考下去,我检查了tags,果然,还是同样的问题。难怪我的tag bloud看上去总是没有什么变化,原来每个tag下面统计的文章数量根本就不一样。

这个bug有一定的“随机性”(当然这是不可能的),有些文章的分类和tag更新成功了,而另一些失败了。具体原因还有待探究。

目前还没有发现有修正这个bug(30号刚刚换的WP2.5)。

今天是今年第一次去游泳,我选了早上九点的时间,水比本来估计的要热一些,很舒服。

不过遗憾的是,基本上没有同龄人,大都是些老头老太太,来锻炼身体的。

我今天游得很认真,基本游足了四十分钟。刚开始,我还比较累,游一个来回要休息一下喘口气,后来很快就适应了,就连续地游。距离上次游泳少说也有半年了,这次连续的游让我又了新的体会。我在连续游一段时间以后,会感到自己的意识从身体里出来了,在水面上漂浮着,注视着自己,想着很多奇妙的事情。比如我昨天一天干了什么,我今天打算干什么,早上背的单词还记得几个,等等等等。

不过最让我惊讶的还是我发觉自己呼吸得很认真,我就想,如果不是在水里,一定觉得空气是那么自然而然的东西,根本不会像现在这样,我盘算着还有大概5秒钟,我就可以把头伸出水面了,在此之前,一定要把现在肺里的气吐空,蹬腿完毕了,要保持住平衡飘一会儿,然后手夹水的动作要领到底是怎样的,因为一定要确保自己的头能举到水面上面,而且还要有足够的时间。每一次呼吸,我都要完成一系列的思考,当然不占用什么CPU的,但是还是有意识的,我想,我是呼吸得如此认真。那种感觉真的挺奇怪的。

然后,我又联想到了处在一段恋爱关系中,是不是也有的时候把对方当成了空气一般对待,好像觉得空气总是在身边,随时呼吸一口,深一点,浅一点无所谓,多一口少一口,无所谓。其实恋爱中的双方如果把对方当成是游泳时候呼吸的空气,每吸一口气,都那么努力认真,都那么踏踏实实,绝不会有一次偷懒,那么两个人应该都可以很享受这段关系,就好像在游泳的时候,你可以享受畅游的乐趣一样。

哈哈,扯远了呢~~还是太理想主义了呢~

周末在家,看到了关于“小神鹿”的报道,没有去记她的名字,也没有去记那个教练的名字。因为我觉得,他们终将会被人们所淡忘。

8岁,一个骨骼还没有发育健全的女孩子,被教练带着练习马拉松,又一个想要创造神话的人。

07年,中国红了两个典型,一个是刘翔,一个是丁俊辉。刘翔是科学训练的象征,他的成功使得孙海英进入了中国田径队,开创了科学训练的时代,马俊仁那套往死里练的法子终于退出了历史的舞台。

而丁俊辉,开创私人体育训练的时代。在国外,很多运动员从事体育运动都是自发性的行为,只有获得了相当的成绩,国家才开始资助参加大赛。而中国的运动员从一开始就是国家培养的,他们就像国家在外树立形象和争取荣誉的工具一样。从丁俊辉开始,标志着我国在经济进一步发展后,私人从事体育运动成为了可能。

但是丁俊辉只是一个特例,这种模式还没有形成一种可以效仿和可以再现的方式。8岁的这个孩子,玩命练习马拉松,我想只是一种对成功的痴迷的追求,甚至无视科学的规律,是非常不可取的。