2019-2020 领悟的优化 基于c++

背景 这两年来,主要精力集中在使用c++做矩阵计算上,由此总结了一些c++的优化手段,虽然可能几年以后会对现在的水平嗤之以鼻,但至少可以记录一下自己的编程水平增长经历,以下希望随时间持续更新。 所谓代码的优化,个人认为有三个方面:更快,更省,更好看。快指的是时间少,省指的是省空间,好看指代码简洁。这三者有时候会有冲突,而我所追求的则是达到三者的平衡,有时甚至可以兼顾三者,个人的水平毕竟是有限的。对于尚未工作的我来说,更深层次的优化其实掌握得并不多,目前使用的优化,或许也仅限于单机以及平日研究所用。 底层优化 底层优化是我掌握得比较浅薄的方法。其核心在于利用计算机的金字塔物理结构,提高运算效率。CPU运算速度非常快,但数据在外存,也就是磁盘上,而计算通常都是发生在CPU,一个程序,分为计算密集型和io密集型,我通常面对的任务都是计算密集型,所以重点在于充分利用CPU。这里可以存在的优化有: 读写文件优化 通常网上教读写文件的方式是利用fstream,将文件转化为数据流,之后再按照数据类型,一个个地读入和转化数据,这里的优化就可以利用内存和缓存,先将所有的数据读入到内存,之后再进行数据的转换。两种代码如下: int n; ifstream infile(path); infile>>n; int n; ifstream fin(path,std::ios::binary); std::vector<char> buff=vector<char>(fin.seekg(0,ios::end).tellg()); fin.seekg(0,ios::beg).read(&buff[0],static_cast<std::streamsize>(buff.size())); fin.close(); stringstream infile; std::copy(buff.begin(),buff.end(),std::ostream_iterator<char>(infile)); infile>>n; std::vector<char>().swap(buff);//释放内存 减少cache miss 减少cache miss,其核心想法就是,当CPU在计算的时候,需要的变量都在内存里。这件事其实对人脑也适用,例如大部分人其实都不太能一心两用,更不必说反复切换。如果编写了一分钟c++代码,又迅速切换到python,再迅速切换到java,这样有可能会造成用法的混乱,但是要是一个月都在编写c++,那么这个月写c++都是比较通畅的,再切换python,虽然要几天适应,但不用太久又能很熟练地使用。 图的存储...

人生无常,生死如常

如星辰般浩瀚的人啊,我走过世间,一生能认识的人或许只是星空的一角。 统计有意思之处就在于,无论整个星空是多么庞大,我们都可以认为,观测到的点点星光,可以反映整个宇宙的所有情况。 而我短暂的人生,所遇到的种种喜怒哀乐,又同别人的有什么两样呢? 人生匆匆数十载,从时间维度上的采样,又如何不能反映一生的起伏? 人生是如此无常啊,意外总是会降临,我所研究的一切,无非是想用数字去量化一些可能而已,但这无常的一切又怎么预测得完呢? 那日,他走了,那些日子,他们走了。大部分人依然是后知者,后觉者,知道又如何?无非是个空空的叹息而已。 将一切量化,生与死都是1,这是不必计算的。我们将能计算的,放在了生命的长度上。为生命的离去而惋惜,并不是因为死去的1,而是难以想象未来所有的可能性,就此终结而已。 人生不是矩阵,人生是张量,大到无法分解的张量。因此人生的拆解也是唯一的。 我站在生与死的中央,看着消失的记忆,原来还有那么一些名字,刻在心上,即使他们的主人已不在。 一年活356天是无常,一天重复356遍是如常。生死放在个人是无常,放在整个人类上是如常。有些人存在世上,需要羁绊;有些人离开了世上,留下了羁绊,其实没有很多奢求,只是希望羁绊能存在得更久一些,虽然不管活着还是死去,羁绊都会在,只是过去绑在两个人之间,如今只会缠绕在自己的心上。 充满随机的世界啊,我即使探索再多的“定数”,也算不出未来,改变不了结果,能改的只有习惯。 是的,随着老去,习惯,生死,如常。

论文阅读|图上的自监督学习——对比学习论文解读

前言 ​ 本文将围绕最近的一些在图上自监督学习的工作,对其中“Contrastive Learning”的内容进行一些解读,并包括一些自监督学习的思路。 ​ 首先,介绍一篇2020的综述《Self-supervised Learning: Generative or Contrastive》,其内容覆盖了CV、NLP、Graph三个方向自监督学习的成果。而本文会将主要目光放在Graph上的自监督学习。 ​ 文章将自监督学习主要分为三类:Generative、Contrastive、Adversarial(Generative-Contrastive)。目前,个人认为大部分Graph研究的目光都集中在Contrstive Learning上。个人拙见,原因可能与图学习的任务有关,图学习的任务主要集中在分类上(节点分类、图分类),对比学习天然会比生成学习更适用于分类任务,所以或许当生成满足某种性质的随机图任务成为主流之后,生成式模型就会成为主流。而对抗式(Adversarial)的学习,则会在生成式学习、对比式学习都达到瓶颈时,得到更好的发展。目前,在图领域,并未看到Adversarial Learning有惊人表现的文章。 ​ 当笔者初识自监督学习时,通过他人的介绍,仅理解为了一种利用自身性质,标注更多标签的一种手段,但随着论文阅读的增加,对自监督本质的理解越来越迷惑。个人理解,其实任意挖掘对象之间联系、探索不同对象共同本质的方法,都或多或少算是自监督学习的思想。原始的监督学习、无监督学习,都被目所能及的一切所约束住,无法泛化,导致任务效果无法提升,正是因为自监督探索的是更本质的联系,而不是表像的结果,所以其效果通常出乎意料的好。自监督学习的前两类方法,其核心想法其实都是想去探索事物的本质。 ​ 本文重点将放在Contrastive Learning的发展脉络上,对于Generative Learning将只结合《Self-supervised Learning: Generative or Contrastive》介绍一些粗浅的理解。 Generative Self-Supervised Learning 综述中主要介绍了四类基于生成式的自监督模型,最后一类是前三类模型的混合版,而在图学习领域,使用的比较多的应该是第三种,即AE的方法,在后文总结表格中有所体现,这里也就不对混合型生成模型进行描述了。 Auto-Regressive (AR)...

暂别绿茵

完成本科统计最后一场比赛,遗憾的是没能走得更远,没能再多打那么一场。结束时,没有哭,也没有感觉特别激动,与一同退役的师兄拥抱了一下,彼此都明白,散了可能就如此散了。大一时,也是如此这般最后一局打全场,虽败入甲。确是自己还不够强,还不足以能挑起大梁就这样走了。 人生有无数地离别,虽然离开这块绿茵,却也并非意味着永久终结足球。眼前还有更重要的事情需要完成,而我也并不是永久地离开。憧憬着,每年都需要离别,四年来,我送走了黄金一带,然后自己送走自己。这四年里,对过错过,不需要后悔过。汗水会湿了球衣,但不希望也不允许眼泪沾湿它。人总是要学着坚强,学着送别。 幸运的是,能有一项运动,让你喜欢一辈子,就像喜欢一个人一样。 我想,那狂风送走了我的愁绪,恰如入冬的枯草,始终会在明年,再化作腐土,掀起无数春风。那时,我可否躺在青青草地上,看着青年们,亦如当年模样。 时机不会再来,再战之时,只盼,同袍依旧,我无牵挂。 之后已是我的独战,考研不易,唯有忘却所有,专心致志,只待明年考上时,删此文,再上场。

论码农、码商与码士

产生这三个概念还源于学习时,话说某日某人问我,什么EJB。我回答说,所谓EJB就是企业级的Java Bean。那什么是Java Bean呢?就是java里的咖啡豆。劈头盖脸就是一句”我当然认识Bean这个单词”,我都没意识到,原来Bean这个单词是那么简单,以致于我这样的翻译回答是在侮辱对方的智商。 什么是Java Bean呢?我认为还得从Java这门语言的产生说起。程序员经常熬夜,一熬夜就喝咖啡。Java成员在讨论新语言取什么名字时,当时他们在喝咖啡,有人提议叫Java,于是最终名字就定为Java了。这样想来,其实也难怪Java这个单词那么容易被命名作语言名。要我说什么蒙牛、特仑苏,安排给程序员们每晚一瓶牛奶,也许下一个百年,称霸世界的某种新语言就能被命名为特仑苏,想想就刺激。 而Java Bean本质上就是一些可串行化,并有一定规则的Java代码块。所谓Java编程,就像是煮咖啡一样,需要耐心和细心,也就是计算机从西方开始发展,要是从东方开始发展,难说当前最受欢迎的语言应该叫Tea, Java Bean也不再叫Java Bean 而是叫Tea Leaf。总结的说,完成一个泡咖啡艺术,首先先要磨好上佳的咖啡豆,写一个完整的应用,也要先造相对完美的类模块。以Java Bean代表这些可以放在一起,煮出完美咖啡的代码段实在是再好不过。 胡扯了半天还得回到EJB是如何让我想出码商、码士的概念。自古以来,社会中主要有几种角色:士农工商。而写代码的人通常被称之为码农。这也是和这份职业的特色是十分相关的,为农者,勤勤恳恳,最重要的作用是打下了整个计算机界的基础。俗话总说,不要重复造轮子,可是作为码农,谁没有造过几个轮子,虽然可用者不知凡几。当开始写EJB以后,不难发现,EJB的分工可以是十分明确的。EJB的每一个组建是可以订制的,也可以是早已经搭建好的,直接拿来用即可。士农工商的出现,最重要的原因是,社会分工开始进一步明显。有的人善于整体的治理,成为了士官。有的人倾注于底层,专注于每一亩土地的利用,成为了农民;也有的人专注于吸收各自的劳动成功,成为物品的搬运工,成为了商人。总的来说,很久以前,代码界只存在一种人——写代码的人。人人都是农民,人人都是商人,每个人都在索求自己所需要的那部分代码,同时,每个人也都在耕耘,希望能建设出自我的空间。但随着编程语言的开发,特别的Java的变化,要求“程序员们”开始分工,开始只知冰山一角,而不知全貌。架构师就像那码士一般,提出了框架,并不负责每个细节的实现。只需要将码代码的任务交给旁人,就足以规划完成一个庞大的项目。最为明显的EJB可以进行自由买卖、自由装配。 每个程序员花费半生心血所耕耘的土地,是他后半生躺着赚钱的桥梁。辛苦一生研究c语言的程序员万万没想到,这个世界还存在着只用写XML文件就能赚钱的程序员。但程序员总该明白,自己写的代码,或多或少,都传递在这个自由市场中。如今买卖的是Java Bean,很多写Java的程序员再难生存下去,这个世界,做农民提供粮食的人差不多就够了,再多,Java Bean 也就不值钱了。或许我所知的R语言、python 仍处在一个成长期,包的管理还处在平台托管的状态中。假设R不再那么开源,R包可以开始买卖,趋之若鹜的人,将不再造同样包的轮子。既然什么包都能卖,那综合一下爬虫包、表格解析包,一下子一个自动爬解析表格的包就做成了。本质上,只是利用了别人已经写好的两个组件。仔细想想,用谢大大最多的,自动生成rmarkdown,其实质也是利用了pandoc等软件,这不也是利用代码拼接的优势吗? 码农,不能一辈子是码农,总要向码商,码士稍微转变一下。EJB已足以说明问题,程序的安全其实是更重要的一点,这需要更多的码士,研究出一个更为标准,并不断进化的准则,以保证程序的安全性。其次,需要更多的码商,总的来说,EJB已经有足够多的量,而实业中,缺少能够做拼接的人,Java代码写起来本身难度并不大,而更让人头疼的是极其复杂和严格的配置过程。 总结本人,一分码士、三分码农、五分码商、剩下一分爱玩的心,总结起来,甚至称不上程序员,仅仅是一个简单码之学徒罢了。