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,虽然要几天适应,但不用太久又能很熟练地使用。 图的存储...

读取Graph数据的代码

背景 记录读图的一些代码,由于图一般都会储存为稀疏矩阵的形式,否则大图根本无法储存,所以最终返回的都是稀疏矩阵,比较节约空间的是csr matrix。 CSR Matrix and COO Matrix COO Matrix 比较容易理解。从图的角度出发其实就是将每条边都存下来。 要想压缩数据,无论什么方法,其实都是在合并同类项。COO Matrix有什么好压缩的呢?单个顶点出发的边可以将它们的顶点合并,用一个数表示。最终也就得到了CSR Matrix。 CSR Matrix可以理解为,先对顶点都预先编号为0-V,那么只需要记录一下,每个顶点有多少出边和出边的位置即可。CSR Matrix由三个数组构成:offsets、edges、values。有时候,offsets 在某些函数输入会拆分为 PointerB 和 PointE,意思也很简单,即某顶点开始时,已经记录边的数量,和此顶点结束时,会记录边的数量。至于 edges 记录的是边的终点,values 记录边的权重。对 CSR Matrix理解的程度决定了,你能对矩阵计算所沉浸的深度,利用CSR进行图的访问和计算是非常方便的,要使有机会写到 MKL 矩阵运算库的解析,会有更深的理解。 Python 部分...

如何提高Eigen效率

背景 为了加速c++的矩阵计算,MKL是比较好的方案,但MKL写代码实在不太友好,其次容易出bug。MKL计算矩阵乘法速度十分快,但其实对代码优化到极致之后,Eigen矩阵计算速度是可以和MKL媲美的。由此,我也对CMake进行了一定的研究。我主要是从知乎Eigen的速度为什么这么快?中学习到的。我仅作为搬运工,并加入一些自己的实际探索。 优化手段 从知乎中总结: 矩阵乘法,若等式左边的变量与右式相乘变量没有关系,则可以使用 A.noalias() 替代 A -mavx 和 -mfma 两个参数, 若对g++ 编译而言, -O3 可以在编译上优化 写 CMakefile 并链接矩阵加速库 MKL 、 Blas 、Lapack 。 这些都是比较容易实现达到的优化方法。主要讲一下利用MKL优化。 参考资料 [1] https://www.zhihu.com/question/28571059

MKL 的坑与教训

背景 为了加速c++,不可避免的需要使用矩阵运算库。最出名的、一般人用的最多的c++矩阵计算库可能是Eigen,从统计处我知道了Armadillo用的也不少。但说到底,python那些包用的最多的也许最后还是MKL。 MKL全称 Intel Math Kernel Library, 是由Intel 公司开发的,专门用于矩阵计算的库。这个库经过我自己的评测,性能远超 Eigen 和Armadillo,毕竟Eigen 和Armadillo属于开源库,下载方便,但功能其实远不够完善。MKL其实不算免费使用的库,学生可以申请,之所以重新开始写这篇文章,正是因为一年前,我申请的linsence过期了。逼于无奈,我必须另辟蹊径,重新安装和配置这个库。过期的根本原因是MKL的特殊编译器icc过期,但本身MKL的库是可以下只含有MKL部分的版本,方法是选择单独下载 Intel® Math Kernel Library,这里需要下载对应系统的MKL文件,当注册之后,Intel会自动发送可用的lisense到邮箱,这里就不做展示。于我而言,为了方便本地测试,和服务器运行代码,我既配置了MAC的版本也配置了linux的版本,MAC版本的配置相对简单,下载dmg文件后,根据提示安装即可。 使用parallel_studio的配置要稍显简单,只需要在得到license之后,按照安装步骤来即可,麻烦的是得到安装软件的license。只有短期需求时,比较推荐的做法是注册学生账号,以学生身份使用并安装parallel_stduio,结果也许会是license的过期,那时若对MKL仍抱有好感,只需重读此文即可。 编译和配置 安装完成后,会有产生目录:/opt/intel/,一般会有下面几个重要的文件夹: compilers_and_libraries compilers_and_libraries_20XX compilers_and_libraries_20XX.X.XXX mkl 这些就是MKL安装和链接的库和关键。为了在g++编译的时候找到这些库的位置并连接上,需要使用以下的语句: source /opt/intel/mkl/bin/mklvars.sh intel64 source /opt/intel/bin/compilervars.sh intel64...

Kmeans base on Cython

背景 Kmeans 是机器学习比较基础的算法,利用包调用比较容易,未来的算法可以很复杂,但基础都是一样简单的。算法层面尽量写得简单,将优化过程尽量写复杂。由于想使用Cython,先写C++部分,这里需要定义命名空间。头文件代码如下: 代码 KMeans.h #ifndef KMEANS #define KMEANS #include <iostream> #include <Eigen/Dense> using namespace std; using namespace Eigen; namespace cluster { class Kmeans{ public: size_t n_cluster; int max_iter; double...

Alias算法

问题描述 O(1)时间内产生离散随机数的方法。 class Alias{ public: double* p; int* h; int* map1; int* map2; int n; Alias(vector<pair<int, double> > pi){ double sum = 0; n = pi.size(); stack<int> small; stack<int> big;...

各式排序算法及其c语言实现

问题描述 排序算法可以说是算法的一个基础,这里在我水平范围内进行总结和归纳,并给出我自己实现的源码。 以下,归纳基于比较的排序方法,因此,其运行时间上限基本都是O(nlog(n)) 时间对比 排序方法 平均情况 最好情况 最坏情况 辅助空间 稳定性 冒泡排序 \(O(n^2)\) O(n) \(O(n^2)\) O(1) 稳定 插入排序 \(O(n^2)\) O(n) \(O(n^2)\) O(1) 稳定 希尔排序 \(O(nlogn)~O(n^2)\) \(O(n^{1.3})\) \(O(n^2)\) O(1) 不稳定 堆排序 \(O(nlogn)\)...

模式匹配之KMP算法

#问题描述 模式匹配:字串的定位操作通常被称为串的模式匹配 最简单的模式匹配方式:从主串S的第pos个字符起和模式的第一个字符比较之,若相等,则继续逐个比较后续字符;否则从主串S的下一个字符起再重新和模式的字符比较之。依次类推,直至模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则称匹配成功,函数值为和模式T中第一个字符相等的字符在主串中的序号,否则称匹配失败。 模式匹配的改进算法 D.E.Knuth 、V.R.Pratt 和 J.H.Morris同时发现,其算法的本质改变在于:每当一趟匹配过程中出现字符比较不等时,不需要回溯指针,而是利用已经得到的部分匹配结果将模式向右移动尽可能远的一段距离后,继续进行比较。 在此不对算法本身做太多阐述,网上有很多说明,仅仅是,完成我自己在理解此算法之后,写出相应的代码。 求next与nextval与匹配 #include<stdio.h> #include<string.h> #include<malloc.h> #include<memory.h> #include<time.h> void Next1(char *pattern, int next[]){ int length=strlen(pattern); *(next)=0; *(next+1)=1; for(int i=2;i<length;i++){ int aim=i-1; while(pattern[i-1]!=pattern[next[aim]-1]){ aim=next[aim]-1;...

C and C++ HelloWorld

第一篇博客 关于 Hello World C #include<stdio.h> int main(){ printf("HelloWorld"); return 0; } C++ #include<iostream> using namespace std; int main(){ cout<<"HelloWorld"<<endl; }

For Example of very Long Title Would Be Typography Elements in One

NOTE: This markdown cheatsheet is a typography demo for this theme. Check out this post to learn more about this markdown usage when you want to get started with this...

如何用 R Markdown 生成每周实验报告

背景 本科时,我主要交作业的报告,写成 HTML 文件,再转 PDF ,追求“花里胡哨”,让别人看起来很“认真”、很“高端”的感觉。用 Prettydoc写完全没问题,网页很容易加入特效。但 HTML 打印输出结果时,相信很多人都会遇到打印不完整的情况。转变为研究生和博士之后,有时依然需要每周给导师写报告。这时候,还像交作业一样给导师交花里胡哨的 HTML 就有些没有必要了,这样会掩盖汇报的重点。我们得认识到报告实际上是为最终论文准备的。所有实验最终是需要放到论文上的。学术论文需要图表,图表往往需要直观、体现重点。如果是在赶一篇论文,并需要不断反馈实验进度时,那么就应该考虑是否能比较方便地将实验结果放置到最终的论文中。最终论文需要使用规定的 LaTeX 模板完成,所以每周的实验报告如果都用之前的方式写,必然会需要返工,而且效率也不高。 本科不怎么写 LaTeX,所以当时并没有对 LaTeX 的各种功能深入了解。虽然现在依然是半瓶水,但已经足够将 R Markdown 有机地与 LaTeX 结合起来。本文主要记录最近几周,对 R Markdown 与 LaTeX 结合生成 PDF 的一些经历和理解,本质还是一些搬运工作。虽然我本人并没有开发任何其中用到的任何工具和包,但网络上确实很少有系统地展示将这些功能综合起来能做到什么事的博客。希望能吸引更多人对其进行探索,之后也能方便我自己在未来写实验报告和展示,这是本文的目的。 从...

记一次 Prettydoc 的改造

声明 本文的出发点并不是鼓励去“剽窃” Prettydoc 包的成果,而是给一种比较小代价改造模板的流程介绍。 写文章有两种观点,一种叫天下文章一大抄,一种叫站在巨人的肩上可以看得更远。前者在抄袭的道路上越走越远,后者推陈出新发明出更多很有意思的事。(这里希望夹带一些私货,仅之前在统计之都发表了一篇关于 R Markdown 的文章,却发现各种平台未经允许直接转载,甚至有的转载不附加链接,这里必须澄清一点,不是在我个人博客或是统计之都看到我写的统计文章都属于抄袭,请联系本人,将采用发律手段解决。) 本文希望基于一个创作 R Markdown文档的例子 (在电脑上看效果比较好),对 Prettydoc 进行分析。读者可以根据自己的程度和需求,选择是停留在对模板的颜色、字体大小的程度,或是往前走一点——自己发明创造,进行阅读。 改造原理及意义 意义 其实自定义一份模板起初没什么特殊含义,但最近深感创作侵权违法成本太低,举证困难,却苦于没有方法。自定义模板可以设置水印,可以设置选择失效,防止直接复制粘贴。虽然对于会写网页的人来说,这样的设防约等于没设,但是增加一些抄袭成本还是挺有意义的。 初步尝试的失败 最起初的想法是自己写一个模板,然后不断调 CSS 和 HTML 的位置和情况,甚至可以不依托 Prettydoc 定义出自己的模板。但毕竟自己不是前端工程师,没有如此深厚的前端功力。之后的想法是利用已经写好的博客模板,直接迁移到 Prettydoc 上,我自身的博客在 Jekyll 的基础上进行开发,也改造过一些模板,于是从 Jekyll...

基于 R Markdown 的展示模板创建和使用

背景介绍 英语演讲课曾说,幻灯片只是辅助工具,更核心和本质的是演讲者的内容。报告和幻灯片,其本质都是服务于展示知识这个过程,两者有着相通之处,利用 R Markdown 可以特别方便地将一份课程报告转化为课程答辩幻灯片,展示幻灯片填充些内容也就是总结的报告,这四年来,利用两者的转换关系,为我节约了不少时间。 作为排版困难者,我尝试着探索了一些只关注内容的幻灯片和报告的写法,随着四年统计学习,R虽然已经快脱离我的常用语言名单,但我那利用 R Markdown 制作幻灯片和课程报告的经验还是不希望就随着我的不用而消亡。故记录下一些改装模板的经验。本文适合会 R Markdown,想自定义模板的人阅读。 从YAML说起 或许使用 R Markdown 的人,有的甚至不知道什么是 YAML,其实就是在生成模板时,三条横杠框住的参数设置,要学会自定义模板,首先要知道有什么可以改,才能下手,类似于学编程初期时,有的人总对编译链接生成机器代码那一段不屑一顾。生成 PDF、HTML、Word 等等,整个过程就类似于编译的过程。而 YAML 文件,则类似于在命令行写的参数,决定了使用什么参数制作报告。 --- title: "Untitled" author: "author" date: "2019年6月14日" output: html_document...

“神抽”还是“鬼抽”?炉石发牌员偏好探究

背景介绍 《炉石传说》是一款集换式卡牌游戏,玩家根据自己现有的卡牌组建合适的卡组,驱动随从,施展法术,与对手一决高下。而作为一款卡牌游戏,除了自身收藏卡牌之外,取得胜负最为关键的一点在于,关键时候是否能抽到关键的卡牌。不少玩家吐槽炉石传说可能存在一个发牌员,为了增加玩家的游戏时间,对发牌机制做了控制,以达到鬼抽/神抽的目的。而实际上,炉石暗地里调整各种选牌概率也不是第一次了。例如:著名的竞技场11只剑龙骑术,极大的降低了玩家的用户体验。 笔者学习《实验设计》课程中,便希望能利用上课知识,为了验证网络上一直以来对发牌员偏好的猜测,开始了简单的实验。研究游戏动态过程过于复杂,所以以起手发牌换牌为例,完成一次简单的探究——炉石中的起手发牌规律。 一、实验设计 1.数据说明,为了探究抽牌上手的因素,将因变量确定为以下几类: 名称 数据记作 备注 “上手卡牌顺序” 记为”次序” 标识每次实验中,抽到的卡牌 “法力水晶费用” 记为”费用” 取值为0-9+ “卡牌稀有度” 记为”稀有度” 取值为0-3,对应白卡/蓝卡/紫卡/橙卡(卡牌稀有度越高,越难收集,若暴雪公司需要盈利,迎合”人民币玩家”,稀有卡牌的上手率可能会高) “是否为职业卡牌” 记为”职卡” 取值为0/1,1为是职业卡牌 “法术或随从” 记为”法随” 取值为0/1,1为随从牌,0为法术牌 “初始手牌或二次手牌” 记为”牌次” 取值为0/1,1为初始手牌,2为更换手牌后的手牌,这里是为了验证更换手牌是否能得到更好的结果。 2. 实验总体说明,炉石卡牌很多,但每次游戏仅能携带30张卡牌,所以为了方便实验,构造了一个卡组尽量满足均匀设计,进行实验。实验卡牌说明如下: 变量 类型...

空间多维数据展示--涟漪图

1. 研究问题 1.1研究问题背景 多年来,全国雾霾爆发,在地理空间上是否存在规律?2017年全国数学建模大赛提出给“拍照赚钱”任务定价,数据是否在位置上呈现一些规律?越来越多的研究定位在空间数据之上。 多维数据存在着展示上不直观的特点,数据容易“纠缠在一起”,想看出数据的变化规律、空间分布规律存在一定的障碍,通常人们将多维数据投影到二维上,但数据的“纠缠”仍然是比较难解决的,而展示多维数据的变化规律需要有一种能动态变化可视化手段。在看到水滴产生的涟漪、画画时颜色的相互交融时,突发灵感,提出一种新的可视化图——涟漪图。 1.2研究问题说明 多维分类型数据,分类的展示可以用点图轻松展示,但无法体现出多维分类数据的每一个分类的紧密程度,哪些分类间存在着“纠缠”,以及数据变化的主要方向。总的来说,多维数据是不能简单用每个维度的均值来衡量的,于是需要一种动态化展示的方法。 1.3数据说明 本次作业为了降低采集数据成本,使用2017年全国数学建模大赛的部分数据集,但制作涟漪图的核心在于中心点如何选取,目前采用的是kmeans方法,选取核心点,所以核心数据仅剩下两部分,经度、维度。对任意数据集,都可以使用二维投射,将点放置到二位图像中。 2. 方法介绍 2.1涟漪图说明 空间数据存在着重心,从kmeans出发,在聚类之后,数据有着一个核心的中点,借着这个核心的中点,可以在一定规则下画一组曲线集,从例子来说,在空间上确定中心后,可以从中心向外不断扩散,选定步长以后画椭圆,而椭圆实际是有方向的,可以将长轴看作是一个方向,确定中心和方向的椭圆,只再需要两个点即可确定其图形,同时新画的椭圆是可以包含原椭圆的。从另一个中心发射出的椭圆,会与原来的中心的椭圆相交,这样很可能产生新的颜色,这也就和涟漪一样,故我命名其为涟漪图。 2.2算法说明 算法如下: 1. 根据kmeans将数据分类(如果数据本身有分类,其实不需要这一步) 2. 以kmeans确定的中心C,将数据集按照到中心的距离进行排序,按升序排列 3. 选定步长为k,k为每次画椭圆包含进来的点的个数,设i=1 4. 以C为中心,设距离C最近的ik个点中最远的点为A,以|AC|为半长轴,CA的方向为长轴方向,绘制最小的能包含这ik个点的椭圆。 5. i=i+1, 重复步骤4,直到所有点都被椭圆覆盖 2.3算法实现 2.4图片描述分析 1. 目前将数据分作4组,从空间上看,每组数据都从经度方向扩散比较严重,也就是说可能经度是一个比纬度更为重要的一个因素。...

记配置20遍spark多机分布式环境

背景 最近由于论文的关系,设计的算法需要在分布式环境下,测试算法的通信时间通信代价,于是尝试配置了多台机器的分布式环境。由于配置过程较为复杂,其中也遇到许许多多问题,由于各式各样的因素,不得不一直转换不同的环境,完成机器的配置。虽然由于水平不足,犯了许多不必要的配置错误,有的问题看起来比较愚蠢,但为了之后避免踩入相同的坑,也就将这一路以来,不断配置更新的过程写成文章,以方便查找。 配置20遍 最初使用的平台是人大校级计算平台,在这个平台上,可以申请一定数量的机器,然后以科研结果作为经费抵扣。使用此平台的原因是之前有前辈在上面配置过 Spark 环境,而我有一定机会可以直接利用他配置好的成果,然而事情并没有像我想象的那么简单。此时出现了两个主要的问题,其一是该环境并没有真正配置yarn,并不能做到真正的并行;其次实际上此平台的集群是在一个大机器上分割出的小虚拟机组成集群,这样的集群实际上的通信代价是非常低的,这无法体现出我们算法的优势,因此我不得不寻找其他平台。之后就在组里先找了6台服务器,直接利用这6台服务器搭建一个集群,虽然机器数目少一点,但平摊下来,每个机器都比原来的配置要更好。当然事情不会那么顺利,由于我实验操作的数据量极大,我不断试探服务器计算能力的上限,最终这些服务器也难堪重负,纷纷内存耗尽、磁盘耗尽,引发了一系列不好的连锁反应,究其原因是我没有做docker环境隔离(要学的东西还很多)。由于当时论文ddl在即,让我只能在夜间跑代码,完全是不可能完成目标的,因此我不得不使用阿里云下的服务器。之后就搞了16台阿里云服务器,并在上面配置真·分布式环境,此时我已经有了十次左右配置环境的经验,但哪怕如此,又经历了经费不足、神秘bug等等意想不到的问题,但我最终还是勉强完成了论文,初次投稿当然还是被拒了。之后改投论文的过程中,吸取了服务器可能很容易崩,随时可能换机器的现实,尽可能地将许多作业改为了批处理,终于又配置了很多次,最终完成了实验和论文。 分布式环境的成分 HDFS 虽然说使用 Spark without Hadooop 从一定程度上配置或许会简单一点,但为了比较清晰地感受分布式环境,并更好地存储数据,我还是采用了 Hadoop 与 Spark 分开配置的策略,这里使用的 Hadoop 版本为 3.3.1。 (HDFS 其实就是一个分布式的文件管理系统,将数据分布式的存储在不同的机器上,一方面可以存的更多,一方面也是可以使得处理数据更快,数据直接分布在不同机器上,也就省去了从主机向其他机器发送数据的通信过程。) SPARK 这里使用Spark的版本是3.1.2 (Spark 分布式计算的环境,利用这样已有的环境就不需要自己去写通信、底层调度,也不必担心各种死锁的问题。) 由于我是不太会 Scala 的(但是任意一种语言,稍微看看基础代码我还能做到),为了方便上手,这里使用的是 PySpark,...

读取Graph数据的代码

背景 记录读图的一些代码,由于图一般都会储存为稀疏矩阵的形式,否则大图根本无法储存,所以最终返回的都是稀疏矩阵,比较节约空间的是csr matrix。 CSR Matrix and COO Matrix COO Matrix 比较容易理解。从图的角度出发其实就是将每条边都存下来。 要想压缩数据,无论什么方法,其实都是在合并同类项。COO Matrix有什么好压缩的呢?单个顶点出发的边可以将它们的顶点合并,用一个数表示。最终也就得到了CSR Matrix。 CSR Matrix可以理解为,先对顶点都预先编号为0-V,那么只需要记录一下,每个顶点有多少出边和出边的位置即可。CSR Matrix由三个数组构成:offsets、edges、values。有时候,offsets 在某些函数输入会拆分为 PointerB 和 PointE,意思也很简单,即某顶点开始时,已经记录边的数量,和此顶点结束时,会记录边的数量。至于 edges 记录的是边的终点,values 记录边的权重。对 CSR Matrix理解的程度决定了,你能对矩阵计算所沉浸的深度,利用CSR进行图的访问和计算是非常方便的,要使有机会写到 MKL 矩阵运算库的解析,会有更深的理解。 Python 部分...

一些乱七八糟的图片处理

背景 记录一些摸索图片处理过程中,看到的,和自己研究的图片预处理方法 图片移动 # 给定判断函数的批量图片移动 import shutil import os def movefile(source_folder,target_folder,condition): #source_folder 原文件夹,target_folder目标文件夹,condition 给定文件路径,判断是否满足移动的条件 filelist=os.listdir(source_folder) for files in filelist: if files[0]==".": continue try: if condition(os.path.join(source_folder,files)): full_path=os.path.join(source_folder,files) des_path=os.path.join(target_folder,files) shutil.move(full_path,des_path) except: print(os.path.join(source_folder,files))...

Kmeans base on Cython

背景 Kmeans 是机器学习比较基础的算法,利用包调用比较容易,未来的算法可以很复杂,但基础都是一样简单的。算法层面尽量写得简单,将优化过程尽量写复杂。由于想使用Cython,先写C++部分,这里需要定义命名空间。头文件代码如下: 代码 KMeans.h #ifndef KMEANS #define KMEANS #include <iostream> #include <Eigen/Dense> using namespace std; using namespace Eigen; namespace cluster { class Kmeans{ public: size_t n_cluster; int max_iter; double...

整理提取图片始

背景 这一切要从我清理手机开始说起,最大占用手机空间的内容当然是手机上的照片。糟糕的是,将照片传到计算机之后,照片就完全乱了,虽然之前也是一团乱麻。想到之前想存图片当壁纸,存了几万张照片,这次可以总结一下,用python对图片做些简单的分类。所以总的说,目标是尽可能提取高清的图片作为壁纸,必要时需要按风格分一下类。其次是手机上不需要的图片且质量差的,或者是无法打开的照片都清理掉。下面是清理过程中的代码: 简单整理图片的思路与实现 准备部分 #与图像处理相关的包 from PIL import Image import cv2 import matplotlib.pyplot as plt import matplotlib.image as mpimg from pylab import * #基础系统和数学包 import math import numpy as np...

Python base skill

标准数据类型 与其他语言十分不一样的是python 封装的几种数据类型 六种数据类型 Number 不用理会浮点型、整数型、为计算带来很多方便,当然不足之处还是运算比较慢,容易不精准计算 String 字符串 从String库提供的字符串处理函数来说,python String相对于其他语言十分的方便和友好 List 列表 主要用[]修饰,比其他语言方便的一点是什么东西都能放,实在是特别好用 Tuple 元组 主要用()修饰,和列表不同之处在于,不可修改 Set 集合 和列表很像,区别是没有重复的项 Dictionary 字典 是我认为除了列表以外最好用的一种容器类型 从Python语言的发明来看,这几种数据类型竟然真的几乎可以覆盖数据工作的方方面面,也就难怪python如此受人欢迎。 而python最为让新手难受,让老手方便的一点,自然是那严格的缩进规则 简单python程序 #python2 print "HelloWorld" #python3 print("HelloWorld")...

记配置20遍spark多机分布式环境

背景 最近由于论文的关系,设计的算法需要在分布式环境下,测试算法的通信时间通信代价,于是尝试配置了多台机器的分布式环境。由于配置过程较为复杂,其中也遇到许许多多问题,由于各式各样的因素,不得不一直转换不同的环境,完成机器的配置。虽然由于水平不足,犯了许多不必要的配置错误,有的问题看起来比较愚蠢,但为了之后避免踩入相同的坑,也就将这一路以来,不断配置更新的过程写成文章,以方便查找。 配置20遍 最初使用的平台是人大校级计算平台,在这个平台上,可以申请一定数量的机器,然后以科研结果作为经费抵扣。使用此平台的原因是之前有前辈在上面配置过 Spark 环境,而我有一定机会可以直接利用他配置好的成果,然而事情并没有像我想象的那么简单。此时出现了两个主要的问题,其一是该环境并没有真正配置yarn,并不能做到真正的并行;其次实际上此平台的集群是在一个大机器上分割出的小虚拟机组成集群,这样的集群实际上的通信代价是非常低的,这无法体现出我们算法的优势,因此我不得不寻找其他平台。之后就在组里先找了6台服务器,直接利用这6台服务器搭建一个集群,虽然机器数目少一点,但平摊下来,每个机器都比原来的配置要更好。当然事情不会那么顺利,由于我实验操作的数据量极大,我不断试探服务器计算能力的上限,最终这些服务器也难堪重负,纷纷内存耗尽、磁盘耗尽,引发了一系列不好的连锁反应,究其原因是我没有做docker环境隔离(要学的东西还很多)。由于当时论文ddl在即,让我只能在夜间跑代码,完全是不可能完成目标的,因此我不得不使用阿里云下的服务器。之后就搞了16台阿里云服务器,并在上面配置真·分布式环境,此时我已经有了十次左右配置环境的经验,但哪怕如此,又经历了经费不足、神秘bug等等意想不到的问题,但我最终还是勉强完成了论文,初次投稿当然还是被拒了。之后改投论文的过程中,吸取了服务器可能很容易崩,随时可能换机器的现实,尽可能地将许多作业改为了批处理,终于又配置了很多次,最终完成了实验和论文。 分布式环境的成分 HDFS 虽然说使用 Spark without Hadooop 从一定程度上配置或许会简单一点,但为了比较清晰地感受分布式环境,并更好地存储数据,我还是采用了 Hadoop 与 Spark 分开配置的策略,这里使用的 Hadoop 版本为 3.3.1。 (HDFS 其实就是一个分布式的文件管理系统,将数据分布式的存储在不同的机器上,一方面可以存的更多,一方面也是可以使得处理数据更快,数据直接分布在不同机器上,也就省去了从主机向其他机器发送数据的通信过程。) SPARK 这里使用Spark的版本是3.1.2 (Spark 分布式计算的环境,利用这样已有的环境就不需要自己去写通信、底层调度,也不必担心各种死锁的问题。) 由于我是不太会 Scala 的(但是任意一种语言,稍微看看基础代码我还能做到),为了方便上手,这里使用的是 PySpark,...

Java HelloWorld

Java HelloWorld //Helloworld.java public class HelloWorld{ public static void main(String args[]){ System.out.println("HelloWorld"); } }

EJB——Ant Demo——simple package

背景 简单的java情况下,使用命令行编译运行一个jar包的demo 目录结构 C:. │ mymanifest │ run.bat │ runjar.bat │ ├─build │ ├─classes │ │ └─AntDemo │ │ HelloWorld.class │ │ │ └─jar │ HelloWorld.jar │ └─src └─AntDemo HelloWorld.java...