title: 【CUDA 基础】5.6 线程束洗牌指令

categories:

- CUDA

- Freshman

tags:

- 线程束洗牌指令

toc: true

date: 2018-06-06 19:53:12



Abstract: 本文介绍线程束洗牌指令的用法

Keywords: 线程束洗牌指令

开篇废话

赶紧写博客,少说废话。

前面介绍了共享内存,常量内存,只读内存的使用,今天我们来研究一个比较特殊的机制,名字也很特殊,叫做线程束洗牌指令。

支持线程束洗牌指令的设备最低也要3.0以上,

洗牌指令,shuffle instruction作用在线程束内,允许两个线程见相互访问对方的寄存器。这就给线程束内的线程相互交换信息提供了了一种新的渠道,我们知道,核函数内部的变量都在寄存器中,一个线程束可以看做是32个内核并行执行,换句话说这32个核函数中寄存器变量在硬件上其实都是邻居,这样就为相互访问提供了物理基础,线程束内线程相互访问数据不通过共享内存或者全局内存,使得通信效率高很多,线程束洗牌指令传递数据,延迟极低,切不消耗内存

线程束洗牌指令是线程束内线程通讯的极佳方式。

我们先提出一个叫做束内线程的概念,英文名lane,简单的说,就是一个线程束内的索引,所以束内线程的ID在 KaTeX parse error: Expected 'EOF', got '\[' at position 1: \̲[̲0,31\] 内,且唯一,唯一是指线程束内唯一,一个线程块可能有很多个束内线程的索引,就像一个网格中有很多相同的threadIdx.x 一样,同时还有一个线程束的ID,可以通过以下方式计算线程在当前线程块内的束内索引,和线程束ID:

unsigned int LaneID=threadIdx.x%32;
unsigned int warpID=threadIdx.x/32;

根据上面的计算公式,一个线程块内的threadIdx.x=1,33,65等对应的laneID都是1

线程束洗牌指令的不同形式

线程束洗牌指令有两组:一组用于整形变量,另一种用于浮点型变量。一共有四种形式的洗牌指令。

在线程束内交换整形变量,其基本函数如下:

int __shfl(int var,int srcLane,int width=warpSize);

这个指令必须好好研究一下,因为这里的输入非常之乱,谁乱?var乱,一个int值,这个变量很明显是当前线程中的一个变量,作为输入,其传递的给函数的并不是这个变量存储的值,而是这个变量名,换句话说,当前线程中有var这个变量,比如我们说1号线程的var值是1,那么2号线程中的var值不一定是1,所以,这个__shfl返回的就是var值,哪个线程var值呢?srcLane这个线程的,srcLane并不是当前线程的束内线程,而是结合with计算出来的相对线程位置,比如我想得到3号线程内存的var值,而且width=16,那么就是,015的束内线程接收0+3位置处的var值,也就是3号束内线程的var值,1632的束内线程接收16+3=19位置处的var变量。

这个是非常重要的,虽然有些困难,但是却相当灵活。width的默认参数是32.srcLane我们后面简单的叫他束内线程,注意我们必须心理明白只有width是默认值的时候,他才是真正的束内线程。

图示如下

接着是另一个指令,其主要特点是从与调用线程相关的线程中复制数据。

int __shfl_up(int var,unsigned int delta,int with=warpSize);

这个函数的作用是调用线程得到当前束内线程编号减去delta的编号的线程内的var值,with和__shfl中都一样,默认是32,作用效果如下:

如果是with其他值,我们可以根据前面的讲解,把线程束再分成若干个大小为with的块,进行上图的操作。

最左边两个元素没有前面的delta号线程,所以不做任何操作,保持原值。

同样下一个指令是上面的反转版本:

int __shfl_down(int var,unsigned int delta,int with=warpSize);

作用和参数和up一模一样,图示如下:

最后一个洗牌指令比较夸张,也是很灵活的一个指令

int __shfl_xor(int var,int laneMask,int with=warpSize);

xor是异或操作,这个指令如果学过硬件或者c语言学的比较扎实的人可能知道,这是电路里面最最最最最重要的操作,没有之一,什么是异或?逻辑中我们假设只有0,1两种信号,用 “^”表示异或:

0^0=0;
1^0=1;
0^1=1;
1^1=0;

二元操作,只要两个不同就会得到真,否则为假

那么我们的__shfl_xor操作就是包含抑或操作在内的洗牌指令,怎么算呢?

如果我们输入的laneMask是1,其对应的二进制是 000⋯001000\cdots001000⋯001 ,当前线程的索引是031之间的一个数,那么我们用laneMask与当前线程索引进行抑或操作得到的就是目标线程的编号了,这里laneMask是1,那么我们把1与031分别抑或就会得到:

000001^000000=000001;
000001^000001=000000;
000001^000010=000011;
000001^000011=000010;
000001^000100=000101;
000001^000101=000100;
.
.
.
000001^011110=011111;
000001^011111=011110;

这就是当前线程的束内线程编号和目标线程束内县城编号之间的对应关系,画成图会非常犀利:

这就是4个线程束洗牌指令对整形的操作了。对应的浮点型不需要该函数名,而是只要把var改成float就行了,函数就会自动重载了。

线程束内的共享内存数据

完整内容 https://face2ai.com/CUDA-F-5-6-线程束洗牌指令/

【CUDA 基础】5.6 线程束洗牌指令的更多相关文章

  1. 【CUDA 基础】5.0 共享内存和常量内存

    title: [CUDA 基础]5.0 共享内存和常量内存 categories: - CUDA - Freshman tags: - 共享内存 - 常量内存 toc: true date: 2018 ...

  2. CUDA基础介绍

    一.GPU简介 1985年8月20日ATi公司成立,同年10月ATi使用ASIC技术开发出了第一款图形芯片和图形卡,1992年4月ATi发布了Mach32图形卡集成了图形加速功能,1998年4月ATi ...

  3. Fisher–Yates shuffle 洗牌算法(zz)

    1,缘起 最近工作上遇到一个问题,即将一组数据,比如[A,B,C,D,E]其中的两个B,E按随机排列,其他的仍在原来的位置: 原始数组:[A,B,C,D,E] 随机字母:[B,D] 可能结果:[A,B ...

  4. 【CUDA 基础】3.2 理解线程束执行的本质(Part I)

    title: [CUDA 基础]3.2 理解线程束执行的本质(Part I) categories: CUDA Freshman tags: 线程束分化 CUDA分支 toc: true date: ...

  5. 【并行计算-CUDA开发】CUDA线程、线程块、线程束、流多处理器、流处理器、网格概念的深入理解

    GPU的硬件结构,也不是具体的硬件结构,就是与CUDA相关的几个概念:thread,block,grid,warp,sp,sm. sp: 最基本的处理单元,streaming processor  最 ...

  6. 【CUDA 基础】2.3 组织并行线程

    title: [CUDA 基础]2.3 组织并行线程 categories: CUDA Freshman tags: Thread Block Grid toc: true date: 2018-03 ...

  7. Java基础知识强化之集合框架笔记71:模拟斗地主洗牌和发牌并对牌进行排序的案例

    1. 模拟斗地主洗牌和发牌并对牌进行排序的原理图解: 2. 代码实现: 思路: • 创建一个HashMap集合 • 创建一个ArrayList集合 • 创建花色数组和点数数组 • 从0开始往HashM ...

  8. Java基础知识强化之集合框架笔记70:模拟斗地主洗牌和发牌(ArrayList)

    1. 模拟斗地主洗牌和发牌 分析:     A:创建一个牌盒     B:装牌     C:洗牌     D:发牌     E:看牌 2. 代码实现: package cn.itcast_03; im ...

  9. JAVA程序设计(11)-----面对对象0基础设计 麻将 创建麻将牌 然后洗牌 发牌~ 恩 就这样

    zzzzZZZZ 1.開始还想贴图的 实在太懒了-- 这是一张麻将 package com.lovo; import java.awt.Graphics; import java.awt.Image; ...

随机推荐

  1. Pygame小游戏练习一

    @Python编程从入门到实践 Python项目练习 一.安装Python包Pygame 通过pip安装包工具安装 python3 -m pip --version #查看是否安装pip 确定安装pi ...

  2. 使用jenkins 构建时,字体图标报错的问题。

    最近一个项目开发中,我们在本地进行项目打包时,可以正常打包. 但是在使用jenkins构建时,一直报错,提示无法加载字体文件.can't resolve module '....xxxx.TTF ' ...

  3. javascript之取余数、去商、天花板取整、地板取整

    demo1: console.log('//求余数'); //求余数 console.log(5 % 4); console.log(6 % 4); //求商 console.log('//求商'); ...

  4. 「网络流 24 题」最长 k 可重区间集

    给定区间集合$I$和正整数$k$, 计算$I$的最长$k$可重区间集的长度. 区间离散化到$[1,2n]$, $S$与$1$连边$(k,0)$, $i$与$i+1$连边$(k,0)$, $2n$与$T ...

  5. fish redux 个人理解

    fish redux 理解 fish redux是什么 Fish Redux 是一个基于 Redux 数据管理的组装式 flutter 应用框架, 它特别适用于构建中大型的复杂应用. 它的特点是配置式 ...

  6. 【ES6 】Promise

    Promise对象定义: 用来处理异步编程 Promise对象的特点 对象的状态不受外界影响 一旦状态改变,就不会再变,任何时候都可以得到这个结果 Promise对象的状态 pending(进行中) ...

  7. sql server 语句书写注意事项

    1  Between在某些时候比IN 2 在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源.他的创建同是实际表一样 3 尽量少用视图,它的效率低.对视 ...

  8. libusb移植

    下载 https://sourceforge.net/projects/libusb/ 编译 # ./configure --build=i686-linux --host=arm-linux --p ...

  9. Spring Cloud(十一)高可用的分布式配置中心 Spring Cloud Bus 消息总线集成(RabbitMQ)

    详见:https://www.w3cschool.cn/spring_cloud/spring_cloud-jl8a2ixp.html 上一篇文章,留了一个悬念,Config Client 实现配置的 ...

  10. win10 增加一个新磁盘

    1.右键我的电脑,选择管理 可以看到C盘的空间相比较大,拿出来250G的空间做成E盘 2.选择OS(C:),右键,压缩卷,请稍后,点击压缩 3.此刻会看到,有一块黑色区域就是新建的未分配空间,这时我们 ...