CUDA中的Warp Shuffle

Warp Shuffle Functions

__shfl_sync、__shfl_up_sync、__shfl_down_sync 和 __shfl_xor_sync 在 warp 内的线程之间交换变量。

由计算能力 3.x 或更高版本的设备支持。

弃用通知:__shfl、__shfl_up、__shfl_down 和 __shfl_xor 在 CUDA 9.0 中已针对所有设备弃用。

删除通知:当面向具有 7.x 或更高计算能力的设备时,__shfl、__shfl_up、__shfl_down 和 __shfl_xor 不再可用,而应使用它们的同步变体。

作者添加:这里可能大家对接下来会提到的threadIndex, warpIdx, laneIndex会比较混淆.那么我用下图来说明.

1. Synopsis

T __shfl_sync(unsigned mask, T var, int srcLane, int width=warpSize);
T __shfl_up_sync(unsigned mask, T var, unsigned int delta, int width=warpSize);
T __shfl_down_sync(unsigned mask, T var, unsigned int delta, int width=warpSize);
T __shfl_xor_sync(unsigned mask, T var, int laneMask, int width=warpSize);

T 可以是 int、unsigned int、long、unsigned long、long long、unsigned long long、float 或 double。 包含 cuda_fp16.h 头文件后,T 也可以是 __half 或 __half2。 同样,包含 cuda_bf16.h 头文件后,T 也可以是 __nv_bfloat16 或 __nv_bfloat162

2. Description

__shfl_sync() 内在函数允许在 warp 内的线程之间交换变量,而无需使用共享内存。 交换同时发生在 warp 中的所有活动线程(并以mask命名),根据类型移动每个线程 4 或 8 个字节的数据。

warp 中的线程称为通道(lanes),并且可能具有介于 0 和 warpSize-1(包括)之间的索引。 支持四种源通道(source-lane)寻址模式:

__shfl_sync()

从索引通道直接复制

__shfl_up_sync()

从相对于调用者 ID 较低的通道复制

__shfl_down_sync()

从相对于调用者具有更高 ID 的通道复制

__shfl_xor_sync()

基于自身通道 ID 的按位异或从通道复制

线程只能从积极参与 __shfl_sync() 命令的另一个线程读取数据。 如果目标线程处于非活动状态,则检索到的值未定义。

所有 __shfl_sync() 内在函数都采用一个可选的宽度参数,该参数会改变内在函数的行为。 width 的值必须是 2 的幂; 如果 width 不是 2 的幂,或者是大于 warpSize 的数字,则结果未定义。

__shfl_sync() 返回由 srcLane 给定 ID 的线程持有的 var 的值。 如果 width 小于 warpSize,则 warp 的每个子部分都表现为一个单独的实体,其起始逻辑通道 ID 为 0。如果 srcLane 超出范围 [0:width-1],则返回的值对应于通过 srcLane srcLane modulo width所持有的 var 的值 (即在同一部分内)。

作者添加:这里原本中说的有点绕,我还是用图来说明比较好.注意下面四个图均由作者制作,如果有问题,仅仅是作者水平问题-_-!.

__shfl_up_sync() 通过从调用者的通道 ID 中减去 delta 来计算源通道 ID。 返回由生成的通道 ID 保存的 var 的值:实际上, var 通过 delta 通道向上移动。 如果宽度小于 warpSize,则warp的每个子部分都表现为一个单独的实体,起始逻辑通道 ID 为 0。源通道索引不会环绕宽度值,因此实际上较低的 delta 通道将保持不变。

__shfl_down_sync() 通过将 delta 加调用者的通道 ID 来计算源通道 ID。 返回由生成的通道 ID 保存的 var 的值:这具有将 var 向下移动 delta 通道的效果。 如果 width 小于 warpSize,则 warp 的每个子部分都表现为一个单独的实体,起始逻辑通道 ID 为 0。至于 __shfl_up_sync(),源通道的 ID 号不会环绕宽度值,因此 upper delta lanes将保持不变。

__shfl_xor_sync() 通过对调用者的通道 ID 与 laneMask 执行按位异或来计算源通道 ID:返回结果通道 ID 所持有的 var 的值。 如果宽度小于warpSize,那么每组宽度连续的线程都能够访问早期线程组中的元素,但是如果它们尝试访问后面线程组中的元素,则将返回他们自己的var值。 这种模式实现了一种蝶式寻址模式,例如用于树规约和广播。

新的 *_sync shfl 内部函数采用一个掩码,指示参与调用的线程。 必须为每个参与线程设置一个表示线程通道 ID 的位,以确保它们在硬件执行内部函数之前正确收敛。 掩码中命名的所有非退出线程必须使用相同的掩码执行相同的内在函数,否则结果未定义。

3. Notes

线程只能从积极参与 __shfl_sync() 命令的另一个线程读取数据。 如果目标线程处于非活动状态,则检索到的值未定义。

宽度必须是 2 的幂(即 2、4、8、16 或 32)。 未指定其他值的结果。

4. Examples

4.1. Broadcast of a single value across a warp

#include <stdio.h>__global__ void bcast(int arg) {int laneId = threadIdx.x & 0x1f;int value;if (laneId == 0)        // Note unused variable forvalue = arg;        // all threads except lane 0value = __shfl_sync(0xffffffff, value, 0);   // Synchronize all threads in warp, and get "value" from lane 0if (value != arg)printf("Thread %d failed.\n", threadIdx.x);
}int main() {bcast<<< 1, 32 >>>(1234);cudaDeviceSynchronize();return 0;
}

4.2. Inclusive plus-scan across sub-partitions of 8 threads

#include <stdio.h>__global__ void scan4() {int laneId = threadIdx.x & 0x1f;// Seed sample starting value (inverse of lane ID)int value = 31 - laneId;// Loop to accumulate scan within my partition.// Scan requires log2(n) == 3 steps for 8 threads// It works by an accumulated sum up the warp// by 1, 2, 4, 8 etc. steps.for (int i=1; i<=4; i*=2) {// We do the __shfl_sync unconditionally so that we// can read even from threads which won't do a// sum, and then conditionally assign the result.int n = __shfl_up_sync(0xffffffff, value, i, 8);if ((laneId & 7) >= i)value += n;}printf("Thread %d final value = %d\n", threadIdx.x, value);
}int main() {scan4<<< 1, 32 >>>();cudaDeviceSynchronize();return 0;
}

4.3. Reduction across a warp

#include <stdio.h>__global__ void warpReduce() {int laneId = threadIdx.x & 0x1f;// Seed starting value as inverse lane IDint value = 31 - laneId;// Use XOR mode to perform butterfly reductionfor (int i=16; i>=1; i/=2)value += __shfl_xor_sync(0xffffffff, value, i, 32);// "value" now contains the sum across all threadsprintf("Thread %d final value = %d\n", threadIdx.x, value);
}int main() {warpReduce<<< 1, 32 >>>();cudaDeviceSynchronize();return 0;
}

CUDA中的Warp Shuffle相关推荐

  1. CUDA中SM对线程块的调度

    sm流处理器簇对blocks的调度策略 在cuda中,GPU中的SM(比如GTX650有两个SM处理器)被CPU调度器把线程块逐个分配到SM上,每个SM同时处理这个被分配的线程块,但是每次每个时刻只能 ...

  2. CUDA中grid、block、thread、warp与SM、SP的关系

    首先概括一下这几个概念.其中SM(Streaming Multiprocessor)和SP(streaming Processor)是硬件层次的,其中一个SM可以包含多个SP.thread是一个线程, ...

  3. [原]CUDA中grid、block、thread、warp与SM、SP的关系

    [原]CUDA中grid.block.thread.warp与SM.SP的关系 2015-3-27阅读209 评论0 首先概括一下这几个概念.其中SM(Streaming Multiprocessor ...

  4. java如何给一个链表定义和传值_如何在CUDA中为Transformer编写一个PyTorch自定义层...

    如今,深度学习模型处于持续的演进中,它们正变得庞大而复杂.研究者们通常通过组合现有的 TensorFlow 或 PyTorch 操作符来发现新的架构.然而,有时候,我们可能需要通过自定义的操作符来实现 ...

  5. CUDA中的NVCC编译器详解

    NVCC编译器详解 CUDA C++ 为熟悉 C++ 编程语言的用户提供了一种简单的途径,可以轻松编写由设备执行的程序. 它由c++语言的最小扩展集和运行时库组成. 编程模型中引入了核心语言扩展.它们 ...

  6. 【CUDA编程】Warp Divergence分析

    Warp CUDA编程中,warp是调度和运行的基本单元,目前,每个warp包含32个threads.软件逻辑上,程序员的所有thread是并行的,但是,从硬件的角度来说,实际上并不是所有的threa ...

  7. Cuda中Global memory中coalescing例程解释

    Global memory是cuda中最常见的存储类型,又叫做Device memory,位于Host主机区域上,它的生命周期是在整个Grid里面,大约具有500个cycle latency.在cud ...

  8. CUDA中并行规约(Parallel Reduction)的优化

    Parallel Reduction是NVIDIA-CUDA自带的例子,也几乎是所有CUDA学习者的的必看算法.在这个算法的优化中,Mark Harris为我们实现了7种不同的优化版本,将Bandwi ...

  9. CUDA 中 FFT 的使用

    CUDA 中 FFT 的使用 @(10.CUDA)[CUDA,并行,fft] 1. 流程 使用cufftHandle创建句柄 使用cufftPlan1d(),cufftPlan3d(),cufftPl ...

  10. CUDA中的一些基本概念

    线程 线程是CUDA中并行程序的基本构建,一个线程就是程序中国的一个单一的执行流,就像一件衣服上的一块棉,一块块棉交织在一起组成衣服,同样 一个个线程组成成并行程序. 随着处理器的核越来越多,硬件可以 ...

最新文章

  1. IBM AI辩手对战世界级人类辩手,炒作还是秀肌肉?
  2. java json格式的转换和读取
  3. Google首席软件工程师Joshua Bloch谈如何设计一款优秀的API【附PPT】
  4. 分布式系统与消息的投递
  5. MATLAB 长度和像素_Matlab中短时傅里叶变换 spectrogram和stft的用法
  6. C#开发微信门户及应用(32)--微信支付接入和API封装使用
  7. 动态规划 —— 背包问题 P03 —— 多重背包
  8. fastjson 大写转小写 字段_对象转json字符串,属性首字母大写自动变为小写
  9. 因为未启用行移动功能 不能闪回表
  10. dp - 2016腾讯笔试 A
  11. 蚂蚁金服数据分析平台演进及数据分析方法应用.pdf(附PPT下载链接)
  12. 关于ashx的基本应用
  13. UVa 706 ZOJ 1146 LC-Display
  14. 如何看待Corona渲染器,它是否会影响国内vray渲染器的地位?
  15. Matlab2010b反复激活解决办法
  16. 最长公共子串计算C++
  17. lwj_C#_周总结2 字符串练习
  18. BRD、MRD、PRD
  19. 阿里巴巴基础设施挑战与芯片策略
  20. 逻辑斯谛回归(logistic regression)

热门文章

  1. c++ opencv 读取文件夹里所有图片
  2. 如何解决农村产权交易难的问题
  3. 制作自己的 Cydia 源
  4. python实现火车票查询工具_用 Python 写一个命令行火车票查看器
  5. Python数据分析之股票数据
  6. CSS3中的元素过渡属性transition
  7. rc时间常数定义_时间常数RC的计算方法
  8. Python学习之路-爬虫(四大名著)
  9. 【PyTorch】6.1 正则化之weight_decay
  10. cocos creator 游戏源码_Cocos Creator 3D v1.0.2 正式发布,新增小游戏平台支持