GPU比CPU更适合并行计算

1.前言

并行计算,是相对于串行计算来说的。它是一种一次可执行多个指令的算法,目的是提高计算速度,及通过扩大问题求解规模,解决大型而复杂的计算问题。在当下,CPU速度提升遇到一定的瓶颈,而GPU速度很高,也在不断的去帮CPU承担更多的计算。GPU的更新换代也非常快,成为可以更好提高我们电脑性能,运行速率的。

2.结构​​

GPU比CPU更适合并行计算_第1张图片
从上图结构我们可以看出,CPU的计算单元(ALU)较复杂,但是个数较少;GPU的计算单元相对简单,但是个数很多CPU的控制单元较复杂;GPU的控制单元相对简单,分布在各计算核。CPU的片上缓存(Cache)较大;GPU的片上缓存较小,分布在各计算核。

2.1 设计目的

GPU最开始是专门用来做图像渲染的。图像渲染有以下特点:

  1. 被渲染的场景由非常多的顶点组成

  2. 顶点组成的场景会被光栅化成非常多的片段

  3. 对每个顶点或片段的处理逻辑都是一样的

    这类数据可以称作流数据。流数据具有数据量大和每个数据分量的处理逻辑类似的特点。NVIDIA的GPU中有一个概念是Stream Processor,即流处理器。流处理器处理的数据即为流数据。所以,GPU的设计目标是提高数据吞吐量。

CPU要处理的任务从一开始就特别复杂,它得保证具有复杂控制逻辑的程序快速运行,而且还得支持多任务。多任务要求CPU的运行频率较高,这样才能让用户感觉多个任务是在并发执行,这个涉及到时间切片。所以,GPU的设计目标是低延时。

CPU需要很强的通用性来处理各种不同的数据类型,同时又要逻辑判断又会引入大量的分支跳转和中断的处理。这些都使得CPU的内部结构异常复杂。而GPU面对的则是类型高度统一的、相互无依赖的大规模数据和不需要被打断的纯净的计算环境。可以比喻为,CPU只是单人的可以做奥赛题的天才选手,而GPU是人数众多,但只能做加减题的选手。

3.GPU吞吐量和CPU延迟性

GPU 的功能是优化数据吞吐量。它允许一次通过其内部推送尽可能多的任务,这比 CPU 一次可以处理的任务多得多。这是因为通常情况下,GPU具有比 CPU 多得多的内核。
但是,实际上,我们称内核为 CUDA(计算统一设备体系结构)内核,该内核由 GPU 中的全流水线整数 ALU(算术逻辑单元)和 FPU(浮点单元)组成。在 NVIDIA GPU 架构中,ALU 支持所有指令的完整 32 位精度。并且,对整数 ALU 进行了优化,以有效地支持 64 位扩展精度运算以及各种指令,例如布尔运算,比较,转换,移动,移位,位反向插入,位域提取和填充计数。通常,GPU 的体系结构与 CPU 的体系结构非常相似。它们都利用高速缓存层,全局内存和内存控制器的内存构造。高级 GPU 架构仅涉及数据并行吞吐量计算,并使可用的内核正常工作,而不是像 CPU 那样专注于低延迟高速缓存的访问。

4.线程

GPU

常用的支持GPU通用计算的开发环境OpenCL和Cuda。Cuda是Nvida专属,opencl是通用的。利用CUDA操作GPU的整体流程:
CPU分配空间给GPU(cudaMalloc)
CPU复制数据给GPU(cudaMemcpy)
CPU加载kernels给GPU作计算
CPU把GPU的运算结果复制回来
从软件层面来说,GPU在进行并行计算时,是以核(kernel)为单位进行的。每个核相当于一个功能函数。每个核由若干线程块(thread block)负责运算,而每个线程块又由若干个线程组成。所有的线程由CPU负责发放给GPU设备。
从硬件层面来说,GPU包含若干个流处理器(SM)(越多GPU性能越好),每个流处理器由若干个处理单元和一个存储单元组成,每个流处理器独立并行工作。用以计算CPU发送过来的线程。
当我们执行并行计算时,GPU会将核分配给流处理器进行并行计算。该过程中存在无序和有序两个部分,无序部分保证了程序的并行能力,有序部分保证了程序的逻辑能力。其中无序部分为线程与线程之间无序,有序部分为核与核之间有序。
无序:
1 当对一个核进行处理时,用于处理当前核的每个线程块会随机分配给任意一个流处理器中的任意处理单元进行计算。
2 每个线程的开始结束时间是随机的,不等待原则。需要注意是,由于线程的互相不等待,往往会导致程序出现问题,因此在CUDA编程中会通过设置屏障来解决这个问题.
有序:
1 每个线程块中的线程必定是在同一时间内运行在同一个流处理器中的 。
2 两个有先后逻辑关系的核,则后一个核要等前一个核完成后才执行。
如Cuda GPU的核心是一组可扩展的流式多处理器(Streaming Multiprocessors,SM)。每个GPU有多个SM,每个SM可以支持数百个线程并行操作。kernel启动时,会分配多个block在多个SM上运行,每个SM处理多个块,每个块上的thread并发执行。

CPU

当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。这种方式我们称之为并发。
所谓时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。而不会造成CPU资源浪费。在宏观上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行。但在微观上:由于只有一个CPU,一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间切片,每个程序轮流执行。时间切片:CPU时间切片是将时间进行分割,线程在领CPU时间切片是按线程的出现顺序进行排队,在那一段时间过后CPU会处理下一个线程,而如果该线程工作内容未做完,那么他将会去重新排队。这也说明,时间片不能太长,也不能太短,因为太长,会让靠后的线程处理时间慢,如若他只是一个简单操作,那就会给使用该线程的用户造成不好的体验。太短的话,线程如果工作量大的话就不得不总是重新排队。而后时间一过就立即处理下一个线程,CPU处理一个线程后切换下一个线程叫做上下文切换,上下文切换会损耗时间。

5. 总结

CPU不擅长于进行并行运算,一次最多就执行十几个任务,这个和GPU拥有数以千计的流处理器差太远了,GPU在未来也将逐步的更多承接来自CPU所承担的计算量,从而提高计算速率。例如:很多人慢慢针对GPU开发出对应的挖矿算法进行挖矿(挖矿:相当大的计算量)。

你可能感兴趣的:(开发语言,学习)