- 博客(25)
- 收藏
- 关注
原创 OpenMP task 原理与实例
Openmp自从3.0以后全面走向任务驱动。task机制非常重要,可以显式定义任务,而其余parallel代码块中不用task定义的实际上是隐式任务。抽象来说就是有两个池子:线程池与任务池。闲置的线程会在线程池等待任务。显式任务与隐式任务会放在任务池中等待线程取走。task子句相当于显式定义一个任务。常用在不规则循环(不适用parallel for的循环)与递归函数中。默认任务只能由一个线程执行。当线程遇到task子句时,既可能自己立即执行,也可能将其放入任务池等待别的线程取走。taskwait显式等待
2022-06-08 16:43:08
1898
原创 StrVec类 移动拷贝
StrVec是对vector的仿写。string在内存中连续存放,当内存空间不足时,申请两倍的内存空间,并利用string的移动拷贝进行转移。
2022-06-08 16:25:29
295
1
原创 pthread并行算法求解旅行商问题代码 vector与数组时间效率
前言最近在写一个tsp回溯算法的pthread并行与串行的效率比较。进行的实验是14个城市,给定它们在平面坐标系上的坐标,彼此的距离即为二者的欧几里得距离。求经过这14个城市的最短汉密尔顿回路。并行程序使用了6个线程,串行程序即普通单CPU程序。算法使用的是使用栈模拟递归的回溯法,这种方法的时间复杂度是O(n!)。还有一种动态规划算法,时间复杂度是O(2^n * n ),因为它消除了大量的子问题,比回溯法快的多。但回溯法易于并行实现。栈模拟递归的一般性方法设并行的核数是m,那么每个线程的时间复杂
2022-04-25 15:08:20
1113
原创 正则采样 自适应方法 并行正则采样排序
前言正则采样,就是从原数组中尽量等间隔的取出采样点。最近在学习MPI并行编程,今天手撕并行正则采样排序时遇到一个难题——如何实现正则采样? 这部分在优快云上没人介绍,我自己琢磨了一种自适应的方法。其效果还没有进行大量测试,下面说一下我的思路。代码先贴出代码,后续讨论void regular_samp(int* raw, int count, int* samp, int k){ int step = floor((count - k) / (k + 1)); int j = 0
2022-04-25 14:17:00
379
原创 栈模拟递归的一般性方法 二叉树非递归的后序遍历
用栈模拟递归的可行性首先要明白函数调用的汇编层面的过程。详情参考浅析函数的调用过程在操作系统内存管理层面,main与sum都是有着相同大小的函数栈,在函数栈中存放父函数的寄存器变量、它自己的局部变量、传入参数、返回值等。以在main函数调用sum函数为例。当main函数调用sum函数时,首先函数调用本质上就是...
2022-04-08 16:34:12
1894
原创 操作系统并发性(四) 信号量
信号量的含义信号量是一个有整数值的对象,它的语义针对某个特定的资源,它的值是可用的资源个数的抽象。当值大于零时,值表示可用的资源个数。当值小于零时,值表示正在等待的线程个数。当值等于零时,表示没有线程等待,但是自己无法使用该资源。信号量的底层是利用锁与条件变量实现的,而锁与条件变量的实现又是利用到了底层硬件的支持,包括同步原语,等待队列,休眠机制等操作系统并发性(二):锁操作系统并发性(三):条件变量信号量的API信号量最大的好处就是代码量小,尤其是比条件变量小的多,使用极其方便。/
2022-03-26 15:34:29
1963
原创 pthread分别使用互斥量、条件变量、信号量实现barrier
导入在多线程编程里,路障(Barrier)是一个非常有利的工具。大概有以下几种应用场景;希望各线程重新同步。有一些线程可能在某些阶段执行的相对较快,如果我们需要它们同步进入下一阶段,就要用到Barrier。调试程序。多线程程序不像单线程程序那样可以很方便进行调试。有些时候一些线程的一些变量值被不经意修改导致在运行下一阶段时出现bug。这时候就需要使用Barrier,让大家都停一停,打印自己的变量信息。pthread不提供路障的实现,需要我们自己手动实现。本文提供了三种实现方式。建模barri
2022-03-24 17:10:17
1838
4
原创 系统虚拟化原理 虚拟机 上交现代操作系统
即将保研上交的大佬推荐了一个操作系统的网课,里面有系统虚拟化部分。听得半知半懂,在这里做一个总结。如有疏漏,还请指出。上海交通大学 现代操作系统什么是虚拟 virtualization我个人以为,虚拟就是制造假象。我们虚拟化一台机器,就是利用软件的技术(常常配合硬件的支持)把机器的实际接口包裹成一个fake接口,用户可以使用fake接口而不必使用原有接口操作机器,fake接口往往更加容易被用户使用。比如我们虚拟化内存:物理实在的内存就是一块块dram,计算机通过地址总线选定内存单元,记住一个内存地址
2022-03-19 20:56:05
1623
原创 云计算概念与模型 什么样的应用适合云计算
云计算的概念云计算是一种以网络为中心的计算模式,数据处理和数据存储可以通过互联网访问的大型计算和存储系统集群上更加有效的完成。云计算是一种商业现实:云计算提供可伸缩的弹性计算和存储服务。可以对这些服务使用的资源进行计量,并且用户仅为它们使用的资源付费。云计算中的核心技术虚拟化技术虚拟化技术是什么?说白了就是通过软件提供假象,而这种假象更利于人类使用。我们虚拟化内存,就是把一片片的DRAM片,变成程序员眼中的连续编址的内存地址空间。我们虚拟化CPU,制造了每个应用程序可以独立占有一个CPU的假象。
2022-03-18 21:55:28
1122
原创 操作系统并发性(二):锁
锁的基本思想锁的基本思想与现实中的锁是一致的。比如有一个保险柜中存放着若干现金,由A,B二人共同使用。当A存钱、放钱的时候需要对保险柜上锁,B同理。至于为什么需要上锁,通俗来讲就是在计算机中可能出现这样的情况:A,B同时向保险柜存钱,此时由于操作系统可能引入不合时宜的中断,计算机可能会遗漏A、B其中一人的操作。详见:锁的基本功能锁的基本功能是阻止多个线程同时进入临界区。当线程对锁执行lock操作时,如果锁已经被其他线程锁住,那么可以认为它会阻塞知直到锁被其他线程解开(线程可能进入休眠状态,即告
2022-03-13 21:05:26
1934
原创 操作系统并发性(一):线程、原子性
线程及线程与进程的区别一个线程类似于独立的进程,只有一点区别:它们共享地址空间,从而可以访问相同的内存数据。多个线程可以运行在同一个CPU上,也可以运行在不同的CPU上。为什么有多线程程序经典观点是一个程序只有一个执行点(一个PC),但这在有些情境下不适用。比如我们要实现一个定时器功能:当时间达到S时,使程序离开当前PC,执行另一个模块。那么我们就需要给这个定时器创建一个线程。所谓多线程程序就是该程序可能同时在执行多条指令,这些线程或者运行在不同的CPU上(真正意义的并发),或者通过上下文切换进行
2022-03-13 21:05:17
1447
原创 操作系统并发性(三):条件变量
为什么引入条件变量考虑如下情形:A线程负责删除链表中的一个元素,B线程负责往链表中插入一个元素。对于一个空链表,只有B线程先执行过了,A线程能够执行。条件变量适用于这样的情形:两个线程完成的任务之间有明确的先后顺序。条件变量是一个显示队列,当条件不满足时,线程可以把自己加入队列,等待该条件。如果某个线程改变了该条件,那么它可以唤醒一个或多个等待线程。条件变量API//数据结构pthread_cond_t cond;pthread_mutex_t mutex;//初始化pthread_c
2022-03-13 21:04:51
2159
原创 魔兽世界(三):开战 北京大学慕课C++大作业 代码与思路
类的组织总体思路:自底向上为:Weapon -> Warrior -> HeadQuarter | City -> main函数每个司令部含有一个Warrior的vector,每个Warrior含有一个Weapon的vector。每个City包含两个Warrior*,代表某一时刻在该城市发生战斗的两个Warrior。Weapon类是一个interface class,派生出Arror,Sword,Bomb三个子类。Weapon类的作用就是让武士调用发动一次攻击,并记录该攻击造成
2022-01-21 00:58:45
3276
原创 C++ 改善程序与设计具体做法
命名习惯lhs、rhs分别作为左值与右值pT表示指向一个T型对象的指针rT表示T型对象的一个引用doSomething作为胡写的函数使用Stuff后缀、the前缀类名与名称空间的首字母大写,变量与函数名的首字母小写other、temp等变量名class AccessLevels{public: int getReadOnly(); void doSomething();private: int readOnly; }尽量以const,enum,inline替换#defin
2022-01-20 20:10:40
627
原创 继承与面向对象设计 virtual的替换方式
公有继承是一种 is-a 关系典例一:class Person{...};class Student : public Person {...};典例二:class Bird{public: virtual void fly(); ...};class penguin : public Bird{...};企鹅是一种鸟,这是事实;鸟会飞,也是事实。但在代码这里并不合适,因为企鹅并不会飞。可以如下纠正://method 1class penguin : public Bir
2022-01-15 15:37:44
243
原创 C++接口与实现分离 降低编译依存度的两种做法代码
考虑这样一个接口类:class Date;class Person{public: Person(const string& name, const Date& birthday); const string name() const; const string birthDate() const;private: string theName; Date birthDate;};客户将这样的接口(常作为“person.h" 头文件)引入自己的代码当中。如果对pers
2022-01-15 13:22:34
399
原创 C++ 资源管理 shared_ptr
资源资源就是哪些一旦使用了将来必须归还给系统的东西。比如内存、文件句柄、互斥锁、数据库连接以及网络socket等。这里以内存管理为例。内存管理可能出现的问题使用已被delete的内存没有delete释放内存对同一块内存delete两次什么时候需要动态分配内存当我们需要共享同一个资源( shared_ptr) 或 独占一个资源 (unique_ptr) 时。对于这样的需求,不建议使用动态内存分配:int Size = 105;int* p = new int[Size];更合适的
2022-01-14 15:54:56
498
原创 封装与接口设计 C++类与对象
封装封装的定义:将类的的具体实现细节隐藏在接口之后,可以说封装的工作就是设计接口。接口的定义:类的可访问元素(public成员、友元等),还包括全局函数。服务客户:作为类的设计者,我们的代码大多数时候并不是给自己使用的,而是要给客户(借助我们的代码进行开发的另一批程序员)使用,他们对我们类的实现毫无想法,他们的工作依赖我们高质量的接口。更新维护:大型程序的更新维护必不可少,而良好的封装可以降低更新维护的代价。封装使得我们可以改变实现而只影响有限客户。我们往往需要改变我们类的具体实现方式(下面
2022-01-14 11:21:54
905
原创 举例说明计算机体系结构的八个伟大思想
面向摩尔定律的设计摩尔定律指出单芯片上的集成度没18-24个月翻一番。计算机设计者必须预测其设计完成时的工艺水平,而不是设计开始时的。在过去,程序员可以依赖摩尔定律,无需修改一行代码,就能实现程序每18个月性能翻一番。但现在,摩尔定律接近失效。由于微处理器的功耗已经达到物理极限,微处理器的设计也由单处理器向多处理器转变,现在的程序员需要掌握并行编程能力以充分利用多处理器的优势。并行就是未来!使用抽象简化设计提高硬件和软件生产率的主要技术之一是使用抽象(abstraction)来表示不同的设计层次
2021-12-29 19:24:45
2736
原创 DRAM内存 与SRAM的比较和加速方法 计算机组成原理
DRAM比SRAM慢的原因DRAM使用电容存储电荷的方式存储数据,必须进行周期性的刷新,这也是该结构被称为动态的原因。SRAM使用双稳态触发器存储比特。没有刷新的问题。DRAM的操作时序更为琐碎,需要分时传送行地址与列地址。而DRAM使用行结构的原因也是因为这种结构便于刷新。DRAM的结构组织更为复杂。涉及预充电命令打开或关闭某个bank,激活命令发送行地址并将行内容送入缓冲区。为什么主存使用DRAM便宜。DRAM每比特的硅面积远小于SRAM。功耗低。SRAM每比特用6-8个晶体管,DRA
2021-12-27 16:13:03
2925
1
原创 编译原理 回填拉链实现短路运算 代码
背景本学期有编译原理课程设计,我定义的语言是一个类C语言。过程中遇到了布尔表达式优化处理的难题。这部分上课讲的是回填拉链法,但网上的资料也是很少。遂自己琢磨实现,最终可以实现自定义语言的中间代码生成,使用递归下降法。文法定义<布尔表达式> ::= <布尔项>{|| <布尔项>}<布尔项> ::= <布尔因子>{&& <布尔因子>}<布尔因子> ::= <表达式>[<关系>&
2021-12-23 11:52:36
3212
原创 计算机组成与设计 流水线学习笔记
背景本学期学校开设了计算机组成原理课程与实验。授课老师一言难尽就不提了,实验的内容是单周期CPU的设计,也没有提及流水线技术。流水线是一种能使多条指令重叠执行的实现技术。目前,流水线技术被广泛采用。(没想到写这个学习笔记需要这么久。。。。最后实在是写不下来了。。。)明确为什么重视处理器设计:计算机的性能体现在三个方面:指令数、时钟周期长度和每条指令的时钟周期数。指令数由编译器和指令系统体系结构共同决定。处理器的实现方式决定了时钟周期长度和CPI。这三者又是紧密联系的,如RISC-V指令系统就是
2021-11-26 21:03:05
1123
原创 人工智能作业 八数码启发式搜索与bfs比较
问题描述3×3九宫棋盘,放置数码为1 -8的8个棋牌,剩下一个空格,只能通过棋牌向空格的移动来改变棋盘的布局。要求:根据给定初始布局(即初始状态)和目标布局(即目标状态),如何移动棋牌才能从初始布局到达目标布局,找到合法的走步序列。求解思路八数码问题是一个典型的隐式图搜索问题。我们可以通过图建模将八数码转换为图。八数码每个状态可以用一个九维数组一一对应,我们把它作为图的节点,把空格的上下左右移动对应状态的转移,我们把他作为边。每个状态可以用一个九维数组一一对应,State定义为:typedef
2021-10-28 11:17:53
2041
1
原创 dijkstra+堆优化
昨天看jupyter操作时,偶然翻到了markdown这种标记格式,正好今天算法课老师在贪心模块讲到了Dijkstra算法。一时兴起,用它写我的第一篇blog。本文代码部分大多解约刘汝佳的紫书。如有疏漏,敬请指正。dijkstra原理dijkstra用于求解单源最短路径问题。同时适用于有向图与无向图首先是几个概念dijkstra算法只能用于正权图,也就是说,边的距离都是正数。我们定义集合V是全部节点的集合,集合E是全部边的集合集合,S是(已经找>到了原点F到它的最短距离的节点构成的集合。
2021-10-19 20:34:49
2255
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人