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代码写起来本身难度并不大,而更让人头疼的是极其复杂和严格的配置过程。 总结本人,一分码士、三分码农、五分码商、剩下一分爱玩的心,总结起来,甚至称不上程序员,仅仅是一个简单码之学徒罢了。

情绪

曾经我将纷纷扰扰 封入文字 敲打琢磨 编写着变幻脚本 恍惚时情似水逝 奏键盘钢冰铁冷 忘江湖推杯换盏 战知必败而争之 生知必死仍乐之 随知必离而相恋 刹那欢喜 宇宙不知谁慎为 气上心头 左突右撞 从足到首 也不过是化作冷静 闷足了乌云雾霾 不过也就倾盆淋透 从首到足 分不得 汗与雨 泪或伤 担惊受怕几十年 逃不脱 所有的担心 不过变作你所担心那样 该到的雨会迟 该爱的人会走 该讨厌的事 一个不落...

悲乐

杨絮飘满天地 你说 对那如雪的景 是爱 亦或是恨呢? 痴痴纠结爱恨着 你说 对那逝去的情感 是悲 抑或是喜呢? 唯余开败的玉兰 远去的行人 照下的是一瞬的哀乐吗 悲喜皆是短暂 爱又能不变吗? 一道道花剑 刺向那地的无情 回忆里触碰的一切 已成了满心悲伤 而回忆却是欣喜若狂 夜色憨憨 即使众星环绕 也因那种深沉 而彻底阴暗 孤独若是欢喜 哀乐也不过一刹 远离逃不开的曾经 悲乐就是生死 毁掉曾经的一切 幻想未来的一天...

星情

我对星空倾诉思念 星空无所回应 我向姑娘倾诉心意 姑娘无所回应 明亮的眸子都只会 怜悯地望着你 大江袭来长风 她只是留巡 却已添下我心伤痕 深刻的痛楚 将生命填满星光 旁人眼里 不过是无病呻吟 可知 再无人 愿意去读我的心意 若爱你就是爱生命 那怨你永远已无力 这落寞随我成斜影 路灯下 我伴着 折翼的单车 无从修补的情义 纠缠心底 何必奢求 有人懂你 何必等待 有人惜你 何必在乎 有人爱你...

斩思

箭穿云霄破苍穹 相思缠绵痛穿肠 拔刀空有心为鞘 佳人何方情无常 不贪长相依 何必苦相忆 不得溯情溪 山水有何意 独观山海 林涛难息 妄得长啸引飞鹰 思念随去梗塞音 山高水长尽归足底 天遥云淡挥袖手间 纵有齐天志 能与谁人说 藏锋十载 一刀断青丝 结庐钢铁间 遁入红尘中 再难随我意 谁人与柔情 斩遍离愁丝 更难舍余情 唯有时间知 我心自鸣泣