一、为什么需要把并行?
业务需求
性能
二、了解下高手之间的过招(本人望尘莫及呀)
linux之父炮轰并行开发,主张大容量缓存。
他认为:对于并行来说,唯一的用武之地就是图形计算和服务器端,而并行计算在这些领域确实也得到了大量的应用。但是没有任何疑问,并行在其他领域毫无用武之地。
三、下面用图形简单介绍几个概念(网上资料很多,这里就概要下,不过这些概念都好理解)
1.同步(synchronous)和异步(asynchronous)
(1)同步交互:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程;
(2)异步交互:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。
区别:一个需要等待,一个不需要等待,在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式。
可以理解为,同步在同一个执行时间上完成一个时间戳之后,才可以执行下一个时间戳。异步则可以另起一个线程去完成下一个时间戳任务,就是不会占用上一个执行时间。
2.并发(Concurrency)和并行(Parallelism)
并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
并行是在不同实体上的多个事件,并发是在同一实体上的多个事件。
并发是一次处理很多事情,并行是同时做很多事情。
总之:并行是两个线程(或进程)同时执行,并发指一会做这件事情,一会做这件事情,一会做那件之情,他们有个调度的过程。
所以并发编程的目标是充分的利用处理器的每一个核,以达到最高的处理性能。并行只有在多核下才会有。
3.临界区
保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。
4.阻塞(Blocking)和非阻塞(Non-Blocking)
并发级别:
1.阻塞:
当一个线程进入临界区,其他线程必须等待
2.无障碍(非阻塞):
1.无障碍是一种最弱的非阻塞调度
2.自由出入临界区
3.无竞争时,有限步内完成操作
4.有竞争时,回滚数据
3.无锁(非阻塞)
是无障碍的
保证有一个线程可以胜出
while(!atomicVar.compareAndSet(localVar,localVar+1)){
localVar = atomicVar.get();
}
4.无等待(非阻塞)
无锁的
要求所有的线程都必须在有限步内完成
无饥饿的
5.死锁(Deadlock)、饥饿(Starvation)和活锁(LiveLock)
有两个人到饭店吃饭,但是只有两根筷子,他们两个人 一人一根。
死锁场景:两个人互相等待对方拿的一根筷子,各自都不做出让步,永远互相等待下去就发生死锁。
饥饿场景:两个人等待饭店再去拿一双筷子,结果饭店拿的比较慢,他俩等到饿死了,筷子还没有拿来,此时就发生了饥饿。
活锁场景:两个人一直在交换各自持有的筷子,但是无论如何交换,每个人还是各自持有一根筷子,永远也吃不了,此时属于活锁。
活锁:指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试,失败,尝试,失败。
死锁:指的是两个或者两个以上的进程相互竞争系统资源,导致进程永久阻塞。
饥饿:指的是等待时间已经影响到进程运行,此时成为饥饿现象。如果等待时间过长,导致进程使命已经没有意义时,称之为“饿死”。
五、有关并行两个定律
阿姆达尔定律
定义:定义了串行系统并行化后的加速度比的计算公式和理论上限
加速比定义:加速比=优化前系统消耗时/优化后系统消耗时
古斯塔夫森
定义:说明处理器个数,串行比例和加速比之间的关系
由上面两个定律可总结出:优化性能总与n和f有关,虽然阿姆达尔定律增加cpu数量与性能成反比,古斯塔夫森却成正比,两个反例,但他们公式可得,同时控制串行比例与cpu个数(也就行并行)才可能达到性能最优化。