并行处理

一文搞懂并发和并行

喜你入骨 提交于 2019-11-29 18:30:25
并发和并行 是两个非常容易混淆的概念。它们都可以表示两个或多个任务一起执行,但是偏重点有点不同。并发偏重于多个任务交替执行,而多个任务之间有可能还是串行的。并发是逻辑上的同时发生(simultaneous),而并行是物理上的同时发生。然而并行的偏重点在于”同时执行”。 并行(parallel) :指在同一时刻,有多条指令在多个处理器上同时执行。就好像两个人各拿一把铁锨在挖坑,一小时后,每人一个大坑。所以无论从微观还是从宏观来看,二者都是一起执行的。 并发(concurrency) :指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。这就好像两个人用同一把铁锨,轮流挖坑,一小时后,两个人各挖一个小一点的坑,要想挖两个大一点得坑,一定会用两个小时。 严格意义上来说,并行的多个任务是真实的同时执行,而对于并发来说,这个过程只是交替的,一会运行任务一,一会儿又运行任务二,系统会不停地在两者间切换。但对于外部观察者来说,即使多个任务是串行并发的,也会造成是多个任务并行执行的错觉。 实际上,如果系统内只有一个CPU,而现在而使用多线程或者多线程任务,那么真实环境中这些任务不可能真实并行的,毕竟一个CPU一次只能执行一条指令,这种情况下多线程或者多线程任务就是并发的

并发与并行的区别

我只是一个虾纸丫 提交于 2019-11-29 18:30:01
学习多线程的时候会遇到一个名词:并发。这是属于操作系统中的词汇,需要了解并发和并行的区别,从网上搜集了几种说法帮助理解。 一: 并发是指一个处理器同时处理多个任务。 (线程是并发) 并行是指多个处理器或者是多核的处理器同时处理多个不同的任务。 并发是逻辑上的同一时间段发生(simultaneous),而并行是物理上的同时发生。 来个比喻:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。 二: 并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。(进程是并行) 就好像两个人各拿一把铁锨在挖坑,一小时后,每人一个大坑。所以无论从微观还是从宏观来看,二者都是一起执行的。 并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。这就好像两个人用同一把铁锨,轮流挖坑,一小时后,两个人各挖一个小一点的坑,要想挖两个大一点得坑,一定会用两个小时。 并行在多处理器系统中存在,而并发可以在单处理器和多处理器系统中都存在,并发能够在单处理器系统中存在是因为并发是并行的假象,并行要求程序能够同时执行多个操作,而并发只是要求程序假装同时执行多个操作(每个小时间片执行一个操作,多个操作快速切换执行)。 三:

进程的并行和并发

£可爱£侵袭症+ 提交于 2019-11-29 12:07:11
进程的并行和并发 一、进程的并行和并发 并行: 并行是指两者同时执行,比如赛跑,两个人都在不停的往前跑;(资源够用,比如三个线程,四核的CPU ) 并发: 并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A ,交替使用,目的是提高效率。 二、并行和并发的区别 并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,这就要求必须有多个处理器。 并发是从宏观上,在一个时间段上可以看出是同时执行的,比如一个服务器同时处理多个session。 来源: https://www.cnblogs.com/randysun/p/11517319.html

Java 8 (10) CompletableFuture:组合式异步编程

送分小仙女□ 提交于 2019-11-29 10:12:15
Java 8 (10) CompletableFuture:组合式异步编程   随着多核处理器的出现,提升应用程序的处理速度最有效的方式就是可以编写出发挥多核能力的软件,我们已经可以通过切分大型的任务,让每个子任务并行运行,使用线程的方式,分支/合并框架(java 7) 和并行流(java 8)来实现。 现在很多大型的互联网公司都对外提供了API服务,比如百度的地图,微博的新闻,天气预报等等。很少有网站或网络应用汇以完全隔离的方式工作,而是采用混聚的方式:它会使用来自多个源的内容,将这些内容聚合在一起,方便用户使用。 比如实现一个功能,你需要在微博中搜索某个新闻,然后根据当前坐标获取天气预报。这些调用第三方信息的时候,不想因为等待搜索新闻时,放弃对获取天气预报的处理,于是我们可以使用 分支/合并框架 及并行流 来并行处理,将他们切分为多个子操作,在多个不同的核、CPU甚至是机器上并行的执行这些子操作。 相反,如果你想实现并发,而不是并行,或者你的主要目标是在同一个CPU上执行几个松耦合的任务,充分利用CPU的核,让其足够忙碌,从而最大化程序的吞吐量,那么你其实真正想做的是避免因为等待远程服务的返回,或者对数据库的查询,而阻塞线程的执行,浪费宝贵的计算资源,因为这种等待时间可能会很长。Future接口,尤其是它的新版实现CompletableFuture是处理这种情况的利器。

spark性能调优7 算子调优

与世无争的帅哥 提交于 2019-11-29 08:28:27
1。mappartions替换map提高性能 map算子的操作,在一个分区中,数据会一条一条进入函数内部 而mappartions则会把分区中所有数据都导入到函数执行 1、MapPartitions操作的优点: 如果是普通的map,比如一个partition中有1万条数据;ok,那么你的function要执行和计算1万次。 但是,使用MapPartitions操作之后,一个task仅仅会执行一次function,function一次接收所有的partition数据。只要执行一次就可以了,性能比较高。 2、MapPartitions的缺点: 如果是普通的map操作,一次function的执行就处理一条数据;那么如果内存不够用的情况下,比如处理了1千条数据了,那么这个时候内存不够了,那么就可以将已经处理完的1千条数据从内存里面垃圾回收掉,或者用其他方法,腾出空间来吧。 所以说普通的map操作通常不会导致内存的OOM异常。 但是MapPartitions操作,对于大量数据来说,比如甚至一个partition,100万数据,一次传入一个function以后,那么可能一下子内存不够,但是又没有办法去腾出内存空间来,可能就OOM,内存溢出。 3、什么时候比较适合用MapPartitions系列操作 就是说,数据量不是特别大的时候,都可以用这种MapPartitions系列操作

jdk13快来了,jdk8的这几点应该看看!

徘徊边缘 提交于 2019-11-29 05:42:49
说明 jdk8虽然出现很久了,但是可能我们还是有很多人并不太熟悉,本文主要就是介绍说明一些jdk8相关的内容。 主要会讲解: lambda表达式 方法引用 默认方法 Stream 用Optional取代null 新的日志和时间 CompletableFuture 去除了永久代(PermGen) 被元空间(Metaspace)代替 我们来看看阿里规范里面涉及到jdk8相关内容: [外链图片转存失败(img-KtCxHE6Z-1567558600313)(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==)] jdk8开篇 https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html 主要有: 1:lambda表达式:一种新的语言特性,能够把函数作为方法的参数或将代码作为数据。lambda表达式使你在表示函数接口(具有单个方法的接口)的实例更加紧凑。 2:方法引用 是lambda表达式的一个简化写法,所引用的方法其实是lambda表达式的方法体实现,这样使代码更容易阅读 3:默认方法:Java 8引入default

深入浅出计算机组成原理:Superscalar和VLIW-如何让CPU的吞吐率超过1?(第26讲)

不想你离开。 提交于 2019-11-29 03:10:51
一、引子 到今天为止,专栏已经过半了。过去的20多讲里,我给你讲的内容,很多都是围绕着怎么提升CPU的性能这个问题展开的。我们先回顾一下第4讲,不知道你是否还记得这个公式: 程序的CPU执行时间 = 指令数 × CPI × Clock Cycle Time 这个公式里,有一个叫CPI的指标。我们知道,CPI的倒数,又叫作IPC(Instruction Per Clock),也就是一个时钟周期里面能够执行的指令数,代表了CPU的吞吐率。那么,这个指标,放在我们前面几节反复优化流 水线架构的CPU里,能达到多少呢? 答案是,最佳情况下,IPC也只能到1。因为无论做了哪些流水线层面的优化,即使做到了指令执行层面的乱 这说明,无论指令后续能优化得多好,一个时钟周期也只能执行完这样一条指令,CPI只能是1。但是,我们现在用的Intel CPU或者ARM的CPU,一般的CPI都能做到2以上,这是怎么做到的呢? 今天,我们就一起来看看,现代CPU都使用了什么 “黑科技”。 二、多发射与超标量:同一实践执行的两条指令 1、整数和浮点数计算的电路,在CPU层面也是分开的 之前讲CPU的硬件组成的时候,我们把所有算术和逻辑运算都抽象出来,变成了一个ALU这样的“黑盒子”。你应该还记得第13讲到第16讲,关于加法器、乘法器、乃至浮点数计算的部分,其实整数的计算和 浮点数的计算过程差异还是不小的。实际上

Java并发编程核心概念一览

≡放荡痞女 提交于 2019-11-29 01:50:55
并行相关概念 同步和异步 同步和异步通常来形容一次方法的调用。同步方法一旦开始,调用者必须等到方法结束才能执行后续动作;异步方法则是在调用该方法后不必等到该方法执行完就能执行后面的代码,该方法会在另一个线程异步执行,异步方法总是伴随着回调,通过回调来获得异步方法的执行结果。 并发和并行 很多人都将并发与并行混淆在一起,它们虽然都可以表示两个或者多个任务一起执行,但执行过程上是有区别的。并发是多个任务交替执行,多任务之间还是串行的;而并行是多个任务同时执行,和并发有本质区别。 对计算机而言,如果系统内只有一个 CPU ,而使用多进程或者多线程执行任务,那么这种情况下多线程或者多进程就是并发执行,并行只可能出现在多核系统中。当然,对 Java 程序而言,我们不必去关心程序是并行还是并发。 临界区 临界区表示的是多个线程共享但同时只能有一个线程使用它的资源。在并行程序中临界区资源是受保护的,必须确保同一时刻只有一个线程能使用它。 阻塞 如果一个线程占有了临界区的资源,其他需要使用这个临界区资源的线程必须在这个临界区进行等待(线程被挂起),这种情况就是发生了阻塞(线程停滞不前)。 死锁\饥饿\活锁 死锁就是多个线程需要其他线程的资源才能释放它所拥有的资源,而其他线程释放这个线程需要的资源必须先获得这个线程所拥有的资源,这样造成了矛盾无法解开; 活锁就是两个线程互相谦让资源

hadoop学习笔记——NO.6_MapReduce_1

吃可爱长大的小学妹 提交于 2019-11-29 01:49:31
hadoop学习笔记——NO.6_MapReduce_1 1.MapReduce原理篇(1) MapReduce是一个分布式运算程序的编程框架,是用户开发”基于hadoop的数据分析应用”的核心框架。 Mapreduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个hadoop集群上。 1.1 为什么要MAPREDUCE 1、海量数据在单机上处理因为硬件资源限制,无法胜任 2、而一旦将单机版程序扩展到集群来分布式运行,将极大增加程序的复杂度和开发难度 3、引入mapreduce框架后,开发人员可以将绝大部分工作集中在业务逻辑的开发上,而将分布式计算中的复杂性交由框架来处理 设想一个海量数据场景下的wordCount需求: 单机版: 内存受限,磁盘受限,运算能力受限 分布式: 1、文件分布式存储(HDFS) 2、运算逻辑需要至少分成2个阶段(一个阶段独立并发,一个阶段汇聚) 3、运算程序如何分发 4、程序如何分配运算任务(切片) 5、两阶段的程序如何启动?如何协调? 6、整个程序运行过程中的监控?容错?重试? 可见在程序由单机版扩成分布式时,会引入大量的复杂工作。为了提高开发效率,可以将分布式程序中的公共功能封装成框架,让开发人员可以将精力集中于业务逻辑。 而mapreduce就是这样一个分布式程序的通用框架

Stream:流水线

梦想的初衷 提交于 2019-11-28 22:46:29
Stream : 流水线 流水线 : 对数据的一组操作 jdk8,添加了新的类 java.util.Stream : Java8中的Stream是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利高效的聚合操作,或者大批量数据操作 Stream的API结合Lambda表达式,极大的提高编程效率和程序可读性 同时它提供串行和并行两种模式进行操作 流操作 java.util.stream.Stream中的Stream接口定义了许多操作。 它们可以分为两大类。 ==1,中间操作 ==: 可以连接起来的流操作 2,终端操作 : 关闭流的操作 终端操作 会从流的流水线生成结果。 其结果是任何不是流的值,比如ListInteger,甚至void。 注:除非流水线上触发一个终端操作,否则中间操作不会执行任何处理。 使用流 流的使用一般包括三件事: 1,一个数据源(如集合)来执行一组操作; 2,一个中间操作链,形成一条流的流水线; 3,一个终端操作,执行流水线,并能生成结果。 ==工具类:Collectors == java.util.stream.Collectors 类 主要作用就是辅助进行各类有用的操作。 eg: 把Stream中的元素进行过滤然后再转为List集合 List list = Arrays.asList(“test”,“hello”,“world”