前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DAY 60:阅读SIMD Video Instructions

DAY 60:阅读SIMD Video Instructions

作者头像
GPUS Lady
发布2018-08-17 14:35:51
6350
发布2018-08-17 14:35:51
举报
文章被收录于专栏:GPUS开发者GPUS开发者

我们正带领大家开始阅读英文的《CUDA C Programming Guide》,今天是第60天,我们正在讲解CUDA C语法,希望在接下来的40天里,您可以学习到原汁原味的CUDA,同时能养成英文阅读的习惯。

关注微信公众号,查看历史信息,可以看到之前的阅读

本文共计208字,阅读时间10分钟

B.24. SIMD Video Instructions

PTX ISA version 3.0 includes SIMD (Single Instruction, Multiple Data) video instructions which operate on pairs of 16-bit values and quads of 8-bit values. These are available on devices of compute capability 3.0.

The SIMD video instructions are:

  • vadd2, vadd4
  • vsub2, vsub4
  • vavrg2, vavrg4
  • vabsdiff2, vabsdiff4
  • vmin2, vmin4
  • vmax2, vmax4
  • vset2, vset4

PTX instructions, such as the SIMD video instructions, can be included in CUDA programs by way of the assembler, asm(), statement.

The basic syntax of an asm() statement is:

An example of using the vabsdiff4 PTX instruction is:

This uses the vabsdiff4 instruction to compute an integer quad byte SIMD sum of absolute differences. The absolute difference value is computed for each byte of the unsigned integers A and B in SIMD fashion. The optional accumulate operation (.add) is specified to sum these differences.

Refer to the document "Using Inline PTX Assembly in CUDA" for details on using the assembly statement in your code. Refer to the PTX ISA documentation ("Parallel Thread Execution ISA Version 3.0" for example) for details on the PTX instructions for the version of PTX that you are using.

本文备注/经验分享:

今天的章节主要提到了N卡上面的Video SIMD Instructions. 注意这里的3个单词:Instructionss虽然说是指令, 但大部分的内容已经导出到了CUDA C(只是手册这里没说, 在另外的一本CUDA Math手册里有), 这种导出的函数实际上我们之前遇到过, 习惯使用CPU的用户知道它们叫intrinsic functions. 然后这里的SIMD, 这个词实际上稍微有点歧义,我们都知道N卡的本质是SIMD的, 同样的一条指令, 被32个SP的阵列(没错, NV就叫这个为SIMD阵列)来执行, 所以实际上说, 所有的N卡指令都是SIMD向量指令. 只是NV通过SIMT的方式, 造成了每个线程都能自由进行的假象, 这样看起来, 每个线程都是标量的, 而今天的SIMD指令, 则不同, 在被切分成32个线程(lanes)后, 每个线程内部, 依然是向量的,例如你今天看到的v*2()和v*4()函数, 分别是指每个线程内部, 还能并行4路或者2路的特殊处理.换句话说, vadd4这种指令, 实际上一个warp平均在一个周期内, 能执行128条, 整个SM(5.X/6.1), 能一次执行512条(计算能力5.x和6.1具有每个SM里128个SP)正因为就算使用了SIMT进行假象掩盖后, 依然是处理是向量的, 所以这些叫SIMD指令.然后回到第一个词Video上, 为何这些指令/函数使用了如此奇怪的名字, 这是因为在引入它们的时候(从计算能力2.0到计算能力3.0左右分批引入的), 当年流行了很一阵子的图像处理, 这些指令能对图像处理过程, 有效的进行加速.所以它们被称为是Video处理指令.这里主要有本章节说的, vadd4/vsub4/vabsdiff4/vmin和max4, 以及, vset4, 注意可以将所有的4替换成2. 含有4的版本是处理8-bit数据的(没错, 如同现在的INT8),而含有2的版本则是处理16-bit数据的, 请注意都是整数.这些数据往往能在图像处理之类的应用中(例如4个8-bit的通道), 得到很好的映射,从而得到提速.具体的用法用户直接应当参考CUDA Math手册, 里面有详细描述.请注意, 该手册里面的版本是导出到CUDA C中的版本, 有一些版本的功能(例如4X并行操作完成后累加), 并没有导出到CUDA C,此时应当考虑使用PTX, PTX的版本中, 功能更加强大.实际上需要说明的是, 这些指令曾经长期只能在PTX中, 后来才慢慢导出到CUDA C的.能导出到CUDA C层次的, 往往代表已经基本定形,以后基本不会修改, 所以可以大胆在项目中使用.这些指令往往能在这些图像处理应用中(也可以是非图像处理应用---只要数据类型和操作适合)取得极高的性能提升.例如vabsdiff4(), 这个版本不仅仅能取得400%的性能(相比基准计算--例如float),还因为它能直接处理被pack打包在一起的4组数据, 相比常规普通计算,例如说: a的4个8-bit分量, b的4个8-bit分量, 然后要求做4个差, 然后取绝对值.这个操作如果没有直接的vabsdiff4支持, 需要的计算量(手工展开+编译后)要远远超过4条的,因为分别需要抽取4次分量, 减法4次, 绝对值4次, 再4个结果打包回去.差不多能有1个数量级左右的提升(只考虑本条, 不考虑其他影响因素).此外, 很多用户使用增加4X的计算器使用量, 通过1个32-bit的寄存器放置8-bit分量, 然后直接运算,这样也可以, 但显著的增加了4倍的资源消耗, 降低了4倍的occupancy.论坛上经常有这种尝试手工重新发明轮子, 费时费力得不到好结果的反面教材:

类似vabsdiff4这种,实际上, 这种拆分到线程(lane)级别, 依然还是向量处理的, 在后期的计算能力, 陆续还引入了很多,例如6.1开始的INT8的__dp4a,可以直接计算4个8-bit分量的D = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3 + C(32-bit);但是从6.1开始, 已经不按照video指令宣传了,你能看到这条新指令具有__dp开头, 这是因为dp是深度学习第一个单词的缩写, 也是这里的本来含义的dot-product(点乘)的缩写.一句两得.实际上以前的__v*4()指令, 这里的v也是vector(向量操作)和video的缩写.NV总是喜欢这样一语双关.实际上如同我们之前经常在论坛上指出的是,新的深度学习指令(INT8, __dp4a), 依然非常适合图像处理的,例如很多时候地图像处理有类似2个滑动窗口, 进行像素对像素的求平方差, 然后求和的运算. 此时可以持续连用: __vabsdiff4() + __dp4a() 前者一次完成了4X的求差处理, 后者继续进行平方求和操作(逐像素).还是很给力的.NV现在不再按照图像处理宣传它们是因为现在流行的重点在于深度学习, 后者能显著的提高推导速度(4X),但是用户要学会应用它们, 不要定死在NV宣传的场合.就如同刚才说的, INT8可以用在图像处理, video instructions也可以用在普通矩阵运算. 只要数据类型和操作合适即可.实际上现在进行图像处理的用户还是很多的,前几天刚刚有个用户想用DGX, 利用它的巨大显存容量+NVLink联合, 进行大幅度的图像处理的,但NV的DGX却是做为深度学习的平台出售的.所以你看, 机器是死的, 人是活的. 很多东西都是通用的(例如本章节的指令), 不一定要卡在原始的宣传应用上. 本章节大致如此,需要补充的两点: (1) 从计算能力2.0开始, 就有了一种非向量(Vector)操作的Video Instruction, 叫vmad, 这个指令虽然含有v字样, 但一次只能处理一组数据, 如同普通的指令一样.但该指令能够方便的抽取出来被打包在一起的8-bit或者16-bit数据(不是FP16, 是16-bit整数),能够节省在运算前后的抽取和打包过程,虽然不能提升运算性能, 但能节省不少寄存器使用量(相比你为了取消打包和抽取过程的存放为32-bit整数的情况),如果数据还需要存放在shared/local或者global memory上的话, 虽然不能提速, 但能降低存储器使用量到2X-4X,如同FP16哪怕是100%速率的--例如AMD的4XX和5XX系列, 虽然不是200%的, 但依然有人用, 因为能节省一半显存.该指令的16-bit版本和Maxwell/Pascal上的XMAD速率一样, 但却可以直接使用(PTX里导出了VMAD, 却没有XMAD),感兴趣的人可以参考一下. (2)虽然手册上标记的这些Video Instruction不是单指令的, 但是编译出来的, 在Maxwell和Pascal上的结果的确是单指令的. 为何手册这样写(手册最后有表, 可以参考), 上不明确.以及, 就算不是单指令的(例如两条指令), 也比你手工展开一大堆的计算序列要好的多的多, 还节省寄存器.因此该用就用(指Maxwell/Pascal), 不需要担忧更多.特别是Pascal, 因为还有了增强的深度学习用的INT8指令, 更加提速了图像处理能力.

此外, 新的INT8和FP16(分别6.1和6.0开始引入),实质上也是本章节的Vector/SIMD指令的.因为它们分别一次能处理4条和2条指令.(后续的tensor core就更多了, 不过tensor的用途比较固定了, 就是乘法和累加),为何现在这些指令不叫SIMD了, 只是出于最近形式宣传的需要.一个人提出, OpenCV要尽快转向FP16计算, 说现在的卡,都在大幅度提升FP16性能(好吧, AMD最近说要上8-bit浮点),如果OpenCV不全面转向FP16, 不提供完善支持, 将会被其他库取代.所以你看, 这就是一个例子, 为了深度学习训练而出现的FP16, 依然可以在图像处理中发挥作用的.其实很多种这样的东西,包括当年, 大家用双精度的卡(其中含有53-bit的整数数据, 其他是浮点值数位和符号位),很多人直接用double来进行uint32_t的整数计算,(很多科学计算领域需要大整数计算能力, 而大整数计算能力往往被拆分成多个32-bit整数的计算序列),因为这些专业卡的double是1/2速率的, 等效具有1/2的32-bit整数计算性能. 而同期的卡一般都是1/4的32-bit整数乘法能力的,这样使用, 能提速到200%

有不明白的地方,请在本文后留言

或者在我们的技术论坛bbs.gpuworld.cn上发帖

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GPUS开发者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • B.24. SIMD Video Instructions
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档