Return to Video

cs344_unit5_17_l_转置代码测量内存使用量

  • 0:00 - 0:04
    所以,如果我们回顾一下针对所有这些内核的分析,
    我们就会看到
  • 0:04 - 0:08
    我们的每元素并行代码版本将达到每秒12.5 千兆字节。
  • 0:08 - 0:13
    我们的每行并行代码版本将获得约每秒1.8 千兆字节,
  • 0:13 - 0:19
    而我们的串行代码版本获得令人失望的每秒0.018 千兆字节。
  • 0:19 - 0:24
    这大约是信鸽的速度。或许,
    一个思考这个问题更好的方式,
  • 0:24 - 0:31
    不在于绝对数字,而是我们使用的特定 GPU 能够实现的百分比。
  • 0:31 - 0:34
    所以,如果我们要算出我们达到的百分比,
  • 0:34 - 0:39
    使用我们执行最好的内核,它大致是31 %的理论峰值带宽,
  • 0:39 - 0:47
    使用我们的每行内核时达到4.5%的理论峰值带宽,
    而我们的串行内核达到小于0.1%的理论峰值带宽。
  • 0:47 - 0:50
    所以,回到问题。为什么这个数字这么低?
  • 0:50 - 0:57
    嗯,我们可以做一个聪明的猜测,
    每当你看到非常低的DRAM 利用率,
  • 0:57 - 1:00
    非常低的百分比带宽,你第一个猜测始终是合并。
  • 1:00 - 1:05
    理解合并的一种方法是 GPU 始终访问全局内存,
  • 1:05 - 1:11
    每次以较大的数据块,
    32 个或 128 个字节来访问DRAM。
  • 1:11 - 1:14
    这意味着我们将需要最少
  • 1:14 - 1:21
    的总内存事务,如果warp中的线程访问连续相邻的内存位置。
  • 1:21 - 1:24
    所以,这是一个很好的合并示例。
  • 1:24 - 1:27
    每个线程在读取或写入一个相邻的内存位置。
  • 1:27 - 1:33
    而且很清楚,如果一个warp中的线程
    在读取或写入完全随机地址和内存,
  • 1:33 - 1:36
    然后你会得到较差的合并,对吗?
  • 1:36 - 1:41
    所以,如果这些访问散布在内存,
  • 1:41 - 1:48
    然后我们要读取的内存块总数
    可能和warp中的线程数一样多。
  • 1:48 - 1:52
    所以,一个随机访问模式显然会导致一个较差的合并。
  • 1:52 - 1:57
    所以,更为常见的访问模式被称为跨步,
    在这种模式下线程访问
  • 1:57 - 2:03
    的内存位置是它们的线程标识与一些步长乘积的函数。
  • 2:03 - 2:13
    所以,例如,线程 0 可能会访问位置 0,线程 1 访问位置 2,线程 2 位置 4、 线程 3 位置 6,等等。
  • 2:13 - 2:17
    在这种情况下,这将是 2步幅,
    因为在线程访问之间有两个元素,
  • 2:17 - 2:25
    跨步访问的范围从,好吧,
    就像在这个例子的 2 个元素的步幅,
  • 2:25 - 2:28
    我真的只增加了一倍的内存事务数。
  • 2:28 - 2:34
    所以我有点儿把我的合并质量
    一直减半到非常非常糟糕的地步,对吗?
  • 2:34 - 2:38
    所以,你可以想象,如果元素之间的跨距足够大,
  • 2:38 - 2:44
    然后在warp中的每个线程访问完全
    不同的 32 或 128 字节的内存块,
  • 2:44 - 2:48
    那么接下来你保证得到很糟的行为。
  • 2:48 - 2:52
    你必须要做的是保证将内存事务的数目最大化。
  • 2:52 - 2:56
    所以,让我们看看我们内核的代码。
    这里是我们从输入矩阵读取得地方,
  • 2:56 - 2:58
    和这实际上表现很不错。
  • 2:58 - 3:05
    每个线程读取内存中的一个值,
    这个值等于某个巨大的偏移;J乘以N加I。
  • 3:05 - 3:09
    如果你看看I,I其实是线程索引再加上一些偏移量。
  • 3:09 - 3:13
    所以,相邻的线程,你知道,那些相邻线程进入season X的线程
  • 3:13 - 3:17
    正在读入输入矩阵的相邻值。这正是我们想要的,
  • 3:17 - 3:21
    所以这是好的合并。另一方面,当我们写入输出矩阵,
  • 3:21 - 3:29
    相邻线程,具有相邻值I的线程,
    写入内存中被N分开的地方,对吗?
  • 3:29 - 3:36
    N 就像 1024。所以,相邻线程正运行在
    相距1024个元素的内存位置。
  • 3:36 - 3:41
    这显然不好,这是很糟的合并。很糟,很糟、很糟、很糟。
  • 3:41 - 3:43
    事实上,这是我们问题的根源。
タイトル:
cs344_unit5_17_l_转置代码测量内存使用量
概説:

more » « less
Video Language:
English
Team:
Udacity
プロジェクト:
CS344 - Intro to Parallel Programming
Duration:
03:44

Chinese, Simplified subtitles

改訂 Compare revisions