一片自留地 Udacity CS344 并行计算入门(二)

magicyang · 2021年03月22日 · 1407 次阅读

从运算开始

1->1 map
多->1/多 gather(求和/求平均,等等)

scatter

gather 的逆操作 scatter,这里得有个图解释下了:

模版 stencil:

Transpose



本节理论化做的很不错的。
在我自己的实际工作中也会经常用到。
主流的神经网络工具:tensorflow 默认的是 NHWC 的数据流,而 pytorch 是 NCHW 的数据流。
不同的排布意味着不同的内存分布。(端侧还是以 NCHW 的排布更多一点,虽然 RGB8888 的排布是 HWC 的,但是神经网络一般运算在 HW 维度重用的概率更高)。

运算类型总结:

GPU 架构:


不同于串行,并行对性能、安全的要求会更高。所以需要了解基础的硬件架构。

SM



这里推荐一篇博文:
https://blog.csdn.net/junparadox/article/details/50540602

并行程序需要并行的内容没有顺序,没有交互:

这也是异构计算产生的原因。O(∩_∩) O
GPU 逻辑运算是不擅长的。

GPU 内部在并行执行的过程中,也会进行约束。

GPU 内存模型:


相比于 CPU 的 L1,L2,L3,GPU 的内存对应 local memory,shared memory,global memory。通常说的显存是 global memory,global memory 可以和 CPU 的内存进行交互。

Barrier

同步的引入:

Barrier:

并行操作会有同步操作

例子:
数组每个元素左移一位:

这里的同步 thread,当所有 thread 结束某行代码后,才会执行后面的代码。
补充一个例子来说明 syncthread:

CUDA


CUDA 正是基于内存、计算、同步而来的架构。

编写并行程序的原则:


在实际的并行计算中,会有两种算子:1.运算密集算子,2.访存密集算子。在实际设计中,这算力和 IO 吞吐量这两个因素是相辅相成的。

减少内存访问时间:


可以看到内存的访问时间也远远小于 host 的访问时间,因此我个人理解:gpu 需要有足够的外部存储存储数据,一次输入一次输出,除此之外不要有和 host 的交互。

这里看一下 cuda 内存的应用:
1.本地内存:


2.全局内存:

注意这里的入参是指针。
主程代码:

3.共享内存:

block 内部的可以通过 shared memory 进行操作,shared memory 的访问比全局内存快。
共享内存会有自己的生命周期,其生命周期就是 block,因此结果数据需要存储在全局内存中。
主程序中的实现和全局内存一致。
内存访问连续最好,因为可以成块预取。现代的计算机都是这样。

读写冲突


多个 thread 同时操作同一个内存区域,会出现内容错误的情况。
和 cpu 一样,这种需要原子操作。

CAS 是 compare and swap 的缩写。
原子操作的修改:

原子操作的缺陷:

避免同一个 block 的 thread 做不同的操作:


but 没讲怎么解决啊。。。。
实际中可以把条件语句进行拆分,把一个运算根据 loop 的条件拆分成两个运算。
比如 1-30 做 A,31-60 做 B,拆分成两个独立的算子。

本节总结:

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册