NVIDIA CUDA 高度并行处理器编程(三):CUDA存储器习题

NVIDIA CUDA 高度并行处理器编程(三):CUDA存储器习题

  1. 习题一中第一题,矩阵加法。可以使用共享存储器减少全局存储器对宽带的消耗吗?
    答:不可以,在每个线程计算一个的 kernel 函数中,每个线程只访问两个所需元素,且每个元素只被访问并加载一次。因为没有元素的重复访问,所以不能使用共享存储器减少全局存储器对宽带的消耗。

  2. 对于分块矩阵乘法,证明全局存储器宽带的减少正比于块的维度大小。
    证明:不用分块的每个元素要加载 n 次,假设块维度 i,则每个块需要加载 n/i + 1 次。得证。

  3. 分块乘法中,忘记使用 __syncthreads(),会发生哪种错误?
    答:加载的一部分不加的话,可能有些元素未加载就被访问,会出错;计算的一部分不加的话,有些线程还没计算完,加载就已经开始了,也会出错。

  4. 如果容量对于寄存器和共享存储器不是问题,解释使用共享存储器要优于寄存器的原因。
    答:共享存储器在块内,线程之间可以相互通信读值,读值时可以通过 warp 合并来增加宽带。

  5. 对于分块矩阵乘法的 kernel 函数,如果使用 32 x 32 的块,那么输入矩阵 M 和 N 的宽带使用率将降到多少?
    答:原使用量的 1/32。

  6. 假定启动一个包含 1000 个线程块的 kernel 函数,每个线程块有 512 个线程。如果一个变量声明为局部变量,那么在 kernel 函数的执行周期里,这个变量会被创建多少个版本?
    答:局部变量保存在局部存储器中,每个线程都会在局部存储器中创建该变量的副本,所以变量数等于线程数为 512000。但局部存储器的实现方式为显存,访问很慢,所以对于线程作用域的变量,尽量声明为自动变量。

  7. 上一题中,如果一个变量声明为共享存储器变量,又会有多少个副本?
    答:一个块一个共享存储器,共有1000个

  8. 考虑两个输入矩阵为 NxN 的矩阵乘法。分别计算在下列两种情况下,输入矩阵在全局存储器中的访问次数:
    a. 没有分块时。
    答:每个元素加载 N 次,N2个元素,共 N3 次。
    b. 分块的大小为 TxT。
    答:分块算法快了 T 倍,共 N3/T 次。

  9. 在一个 kernel 函数中,每个线程完成 36 次浮点运算,并 7 次从全局存储器中访问字长为 32 位的字。对于下列属性的设备,指出这个 kernel 函数术语计算密集型还是缓存密集型。
    a. 峰值性能为 200GFLOPS,峰值宽带为 100GB/s。
    b. 峰值性能为 300GFLOPS,峰值宽带为 250GB/s。
    答:使用每个线程给定的数据计算 FLOPS/byte,本题是 (36/28 = 1.28)。
    然后对A, B (A= 2, B = 1.2)给出的机器定义计算相同的比率。如果从问题中计算出的比率大于A或B中的比率,那么在那台机器上,这个 kernel 是计算密集型的。如果它小于在A或B中计算的比率,那么 kernel 在那台机器上是缓存密集型的。如果它是相同的,那么内核既不是计算密集型也不是缓存密集型,或者两者都是。

猜你喜欢

转载自blog.csdn.net/weixin_45773137/article/details/124900412