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. postman的安装与使用方法介绍

    软件介绍 在我们平时开发中,特别是需要与接口打交道时,无论是写接口还是用接口,拿到接口后肯定都得提前测试一下,这样的话就非常需要有一个比较给力的Http请求模拟工具,现在流行的这种工具也挺多的,像火狐 ...

  2. 贝叶斯优化 Bayesian Optimization

    贝叶斯优化 Bayesian Optimization 2018年07月02日 22:28:06 余生最年轻 阅读数 4821更多 分类专栏: 机器学习   版权声明:本文为博主原创文章,遵循CC 4 ...

  3. MySQL 子查询(一)

    源自MySQL 5.7 官方手册 13.2.10 Subquery Syntax 〇.MySQL子查询介绍 子查询指的是嵌套在某个语句中的SELECT语句. MySQL支持标准SQL所要求的所有子查询 ...

  4. configure,make和make install关系

    linux编译安装中configure.make和make install各自的作用 ./configure是用来检测你的安装平台的目标特征的.configure根据给定的参数和系统环境会生成Make ...

  5. linux——环境变量

    环境变量 基本概念: 一般是指在操作系统中用来指定操纵系统运行环境的一些参数 当我们用动态库链接成功的时候,其实就是相关的环境变量帮助编译器进行查找. 环境变量通常具有某种特殊用途,还有在系统当中通常 ...

  6. hdu 6043 KazaQ's Socks

    规律题.我自己写的规律对长度为2的要特判,wa一万次... 规律题目,容易错的反而是数据小的时候,得长记性. 题解:规律 先是1~n 然后1~n-2 n-1  1~n-2 n 交替出现 比如当n=4 ...

  7. 【原创】大叔问题定位分享(36)openresty(nginx+lua)中获取不到post数据,ngx.req.get_body_data返回nil

    openresty(nginx+lua)中获取不到post数据,ngx.req.get_body_data返回nil This function returns nil if the request ...

  8. 【原创】大叔经验分享(76)confluence和jira配置

    一 下载 confluence https://product-downloads.atlassian.com/software/confluence/downloads/atlassian-conf ...

  9. 【php设计模式】装饰器模式

    装饰器模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能.其结构图如下: Component为统一接口,也是装饰类和被装饰类的基本类型. ConcreteComponent为具体实现类 ...

  10. 在eclipse导入项目的步骤

    1. Import 2. Next 3. 确定  选中copy projects into workspace    Finish 这样项目就导入进来了. 4.导入jar包 Configure Bui ...