办公设备维修网
资讯中心 您所在的位置:网站首页 资讯中心 聊聊多线程、多进程与GPU

聊聊多线程、多进程与GPU

2024-02-12 09:48:09| 来源: 网络整理

在聊进程和线程的概念之前,先简单了解一下CPU的基本组成架构。一个CPU主要由ALU(算术逻辑单元)、寄存器等构成。其中ALU是进行计算的地方。对于多核CPU,每个核都有独立的ALU、寄存器,还有一些缓存组件。

进程与线程

一个程序进入内存,获得系统分配的内存空间,这就是一个进程。进程之间相互独立。一个进程可以有多个线程(任务),同一进程的所有线程共享该进程的内存。

举个例子,windows系统中,每打开一个软件相当于运行一个进程。软件程序是存储在磁盘上的文件,只有把它们加载到内存中,并被操作系统调用,它们才开启生命周期。比如打开QQ音乐,就开启了一个进程;这个进程有多个子任务,如播放音乐、显示歌词、网络通信等等,这些子任务就对应很多个线程。

进程从系统中获取内存资源,并将它分配给线程使用——进程是内存的所有者,线程是内存的使用者。线程是系统调度的最小粒度。

一个ALU同一时间只能处理一个线程。而每个CPU核心只有一个ALU计算单元,所以它同一时间只能处理一个线程。

现在有超线程的概念,如4核8线程,16核32线程——每个CPU核对应两个线程。它背后的原理是,每个核仍然只有一个ALU,但它有两套寄存器和其他元件。不需要切换线程,就可以让ALU在不同时间段处理两个线程。这样,一个CPU物理内核就像两个“逻辑内核”一样。多核CPU的原理 这个视频可以参考。

并发与并行

并发:有处理多个任务的能力,不一定要同时。一个并发要竞争CPU资源,等待执行

并行:有同时处理多个任务的能力。并行是在不同线程在不同CPU核心上执行

上图不同颜色的箭头表示多个任务(线程)。只有一个CPU核心的情况下,多个线程要竞争CPU资源,等待执行;计算单元在不同的线程之间快速切换,宏观上看似多个线程都在被执行,但同一时刻只有一个线程在运行。这就是并发

当有多个CPU核心时,不同线程可以在不同CPU核心上执行。这就是并行

是否能实现并行,取决于服务器的CPU核心数量。

如果开启了很多进程,CPU比较繁忙、资源不足,操作系统只为一个含有多线程的进程分配一个的CPU核心,那么线程之间会竞争CPU资源——这就是通过多线程实现并发。

在CPU资源比较充足的时候,一个进程内的多线程,可能被分配到不同的CPU核心上运行,这就是通过多线程实现并行。

但在多线程实践中,线程的个数往往远远多于CPU的个数,所以多数情况下是并发。

多线程、多进程

每个编程语言的多线程、多进程实现方式不同。如上面所说,Java的多线程是有可能实现并行的。但Python不同。

Python中有一个叫做GIL(全局解释器锁)的东西。它要求一个Python进程中,每个时刻只能有一个线程在执行。 因此,一个Python解释器不能为多个线程分配多个CPU核心。所以Python的多线程只能实现并发,而不能实现真正的并行。

当一个线程被运行时,它拿到GIL,此时同一Python解释器(同一进程)中的其他线程不能运行。遇到 IO 任务时,GIL被释放,此时可以进行线程的切换。

因此Python中多线程适用于IO密集型的场景:防止CPU计算单元在单个线程上等待IO任务,造成计算资源的浪费。

对于计算密集型的任务,可以使用多进程:运行多个Python解释器,在不同CPU核心上运行,实现并行。

Python有两个内置模块:threading和multiprocessing,分别对应多线程与多进程的编程。这两个模块的使用非常类似,具体可以参考这个教程:Python 并发编程实战,用多线程、多进程、多协程加速程序运行

协程

Python还提供了异步IO的模块 asyncio,在单线程内实现并发,这个概念叫做协程。

异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。传统的单线程编程中,程序的运行是同步的(同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行)。而异步的概念则是不保证同步的概念,也就是说,一个异步过程的执行将不再与原有的序列有顺序关系。

asyncio的核心原理,就是一个event-loop(可以理解成 while True 循环)。

上图三个方框表示三个不同的任务。执行完第一个任务的CPU计算部分后,在等待IO的过程中,会进入第二个任务进行CPU计算;以此类推。在执行完第三个任务的CPU计算、等待IO的时候,来到第二次循环,继续第一个任务的CPU计算......

在event-loop的每一次循环中,线程会遍历各个任务,在前面任务IO等待的过程中,进行后面任务的CPU计算。循环往复,直到所有任务执行完毕。

可以看到,协程与多线程一样,也是比较适用于IO密集型的场景,如网络爬虫、Web服务。但线程的开启和销毁需要耗费系统资源,相比之下,协程更加轻量级。Python异步IO实现并发爬虫:这一节视频介绍了协程在爬虫上的简单应用。

更高更快更强?

要提高程序的运行速度,可以极致压榨、充分利用CPU计算单元的计算时间(多线程、协程);也可以把任务分配到多个CPU上运行(多进程)。

而对计算资源要求甚高的深度学习,CPU已经不能满足计算需求了。GPU已经被广泛用于加速神经网络的训练了。GPU比CPU的“核心”更多(前者能达到几千),计算力更强——Goole Colab上一块免费的GPU就可以让训练加速几倍。除了单机单GPU,还可以单机多GPU训练;对于更大的网络,甚至可以搞分布式训练(多机多GPU)。

除了GPU,目前很多公司,包括一些国内大厂都在开发自己的 AI 芯片,它们有个统称——ASIC(专用集成电路),并且都用 “某某PU” 命名。其中最有代表性的当属谷歌的TPU。就像英伟达的GPU有CUDA软件栈的加持,TPU也有 tensorflow 框架的加持(TF对TPU有很好的支持),甚至有Transformer 当红算法的加持——TPU在CNN上做卷积不一定多快,但非常适合部署 Transformer。

AI芯片不仅要比拼运算能力,还要比拼生态。就算阿里“平头哥”的含光NPU在基准Resnet50上性能卓著,但离大规模部署还有很长一段路要走。

鸣谢沐神在这个话题上的科普,见视频:深度学习硬件:CPU 和 GPU、深度学习硬件:TPU和其他



【本文地址】 转载请注明 

最新文章

推荐文章

CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备16040606号-1