01并行介绍

并行

为什么要并行

业务要求,性能

但是进程开销大,一般是多线程。

图像处理、服务端编程 (计算密集型,多核计算机上)

摩尔定律失效,硬件的提升不如软件的优化了

几个重要概念

同步 异步

并发 并行

临界区

阻塞 非阻塞

锁 饥饿 活锁

并行的级别

同步异步

对方法调用而言的。

image-20230304120021559

并发并行

程序的执行:并发(Concurrency)和并行(Parallelism)。单核无区别;多核有区别

image-20230304120111585

临界区

临界区是一种公共(共享)资源,可以被多线程访问。需要被控制,一旦临界区资源被占用,其他线程想要使用这个资源,就必须等待。以防止资源被破坏。

image-20230304120420584

阻塞非阻塞

来形容多线程间的相互影响。

如果一个线程进入临界区,其他想要这个资源的线程就必须等待,导致这些线程被挂起,这就是阻塞。

非阻塞允许多个线程进入临界区。

死锁饥饿活锁

多线程中可能遇到的问题:死锁、饥饿、活锁。

对于阻塞的程序,有可能发生死锁现象。各线程分别占有了一些资源,又需要其他线程持有的资源,导致卡死。

image-20230304121053913

上图,每个小车占有了一条道路,又需要另一条道路,但是另一条道路已经被其他小车占有。

死锁(DeadLock)是静态现象,cpu占用为0. 可以通过线程dump等方式排查。

活锁(LiveLock)是动态现象。

类似电梯遇人问题。两人进出电梯时面对面撞上,同时向一边避让,还是撞上;又同时往另一边靠,还是撞上。。。

A线程拿了资源a,还想要资源b;B线程拿了资源b,还想要资源a;发生了死锁。 然后比如程序有死锁检查机制,A,B线程同时释放了占有的资源。 然后A线程和B线程重新拿取资源,各拿了一个资源,又需要对方的资源;又发生死锁。 又检测到死锁释放资源。。。循环往复。

饥饿

饥饿是指某个线程因为某种原因一直无法获取到所需的资源,导致一直无法执行。比如原子操作CAS竞争一直失败。

并发级别

concurrency并发。按并发的级别分类:

并发分为(阻塞和非阻塞)。

非阻塞进一步分为(无障碍、无锁、无等待)。

阻塞级别

当一个线程进入临界区之后,其他线程必须等待。

无障碍级别

无障碍obstruction-free (最弱非阻塞)

线程自由进入临界区。(先拿系统的快照号)

有竞争时,回滚数据。(操作时发现快照号不是最新,重新获取快照号,重新读取)

无竞争时,有限步骤内完成操作。

比如读坐标(x,y),先读x再读y. 无障碍并发级别,读之前拿一下系统的快照,然后依次读取x和y;如果读取过程中,发现快照号已经改变,重新获取快照号,重新读取x和y。

无锁

无锁Lock-Free

是无障碍的

保证有一个线程可以胜出(保证有一个线程可以顺利的走下去,继而保证整体最终可以完成)

eg:

//可能会有ABA问题?
while(!atomicVar.compareAndSet(localVar, localVar+1)) {
    localVar = atomicVar.get();
}

无等待

无等待Wait-Free

无锁的

要求所有的线程都必须在有限步内完成

必然是无饥饿的。

并行度的计算

两个重要定律:Amdahl定律(阿姆达尔定律)、Gustafson定律(古斯塔夫森定律)

Amdahl定律

Amdahl定律定义了 串行系统改造为并行系统后的加速比的理论上限。

加速比=优化前系统耗时/优化后系统耗时

image-20230304133952821
image-20230304134328567

Gustafson定律

说明处理器个数,串行比例和加速比之间的关系

image-20230304141256665

评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注