三种基于CUDA的归约计算

2023-10-26

归约在并行计算中很常见,并且在实现上具有一定的套路。本文分别基于三种机制(Intrinsic,共享内存,atomic),实现三个版本的归约操作,完成一个warp(32)大小的整数数组的归约求和计算。

Intrinsic版本

基于Intrinsic函数 __shfl_down_sync 实现,使一个warp内的线程通过读取相邻线程寄存器中数据,完成归约操作。
实现如下:

__global__ void kIntrinsicWarpReduce(int* d_src, int* d_dst)
{
	int val = d_src[threadIdx.x];
	//val = __reduce_add_sync(0xFFFFFFFF,val);/*CUDA文档中说这个Intrinsic函数需要计算能力8.x,不知道是哪款显卡*/
	for (size_t delta = (blockDim.x >>1); delta > 0; delta = (delta >> 1))
	{
		val += __shfl_down_sync(0xFFFFFFFF, val,delta, 32);
	}
	if (threadIdx.x == 0)
	{
		d_dst[0] = val;
	}
}

其中,关于函数 __shfl_down_sync 的说明如下,其中英文部分截取自《CUDA_C_Best_Practices_Guide》:
cuda可以用于归约操作的两个Intrinsic指令
unsigned __reduce_add_sync(unsigned mask, unsigned value)

The mask indicates the threads participating in the call.
一个bit位表示一个线程lane,整个warp做归约0xFFFFFFFF

T __shfl_down_sync(unsigned mask, T var, unsigned int delta, int width=warpSize)

width must have a value which is a power of 2;If width is less than warpSize then each subsection of the warp behaves as a separate entity with a starting logical lane ID of 0. If srcLane is outside the range [0:width-1], the value returned corresponds to the value of var held by the srcLane modulo width.
以width分割warp,每width个线程为一组,srclane超过width后做取模处理

共享内存版本

在共享内存中与一个warp中其他线程交换数据,实现归约计算。
代码实现如下:

__global__ void kSMWarpReduce(int* d_src, int* d_dst)
{
	__shared__ int sm[warpsize];
	sm[threadIdx.x] = d_src[threadIdx.x];
	for (size_t step = (warpsize >> 1); step > 0; step = (step >> 1))
	{
		if (threadIdx.x < step)
		{
			sm[threadIdx.x] += sm[threadIdx.x + step];
		}
	}

	if (threadIdx.x == 0)
	{
		d_dst[0] = sm[0];
	}

}

Atomic版本

基于原子操作实现归约:

__global__ void kAtomicWarpReduce(int* d_src, int* d_dst)
{
	atomicAdd(d_dst, d_src[threadIdx.x]);
}

测试程序


const int warpsize = 32;
void TestReduce()
{
	int h_src[warpsize];
	for (size_t i = 0; i < warpsize; i++)
	{
		h_src[i] = i;
	}
	int h_dst = 0;
	int* d_src, * d_dst;
	cudaMalloc(&d_src, warpsize * sizeof(int));
	cudaMalloc(&d_dst, sizeof(int));
	cudaMemcpy(d_src, h_src, warpsize * sizeof(int), cudaMemcpyHostToDevice);
	kIntrinsicWarpReduce << <1,32 >> > (d_src,d_dst);
	checkCUDARtn(cudaDeviceSynchronize());
	cudaMemcpy(&h_dst, d_dst, sizeof(int), cudaMemcpyDeviceToHost);
	printf("kIntrinsicWarpReduce rtn is %d \n", h_dst);
	cudaMemset(d_dst, 0, sizeof(int));
	kSMWarpReduce << <1, 32 >> > (d_src, d_dst);
	checkCUDARtn(cudaDeviceSynchronize());
	cudaMemcpy(&h_dst, d_dst, sizeof(int), cudaMemcpyDeviceToHost);
	printf("kSMWarpReduce rtn is %d \n", h_dst);
	cudaMemset(d_dst, 0, sizeof(int));
	kAtomicWarpReduce << <1, 32 >> > (d_src, d_dst);
	checkCUDARtn(cudaDeviceSynchronize());
	cudaMemcpy(&h_dst, d_dst, sizeof(int), cudaMemcpyDeviceToHost);
	printf("kAtomicWarpReduce rtn is %d \n", h_dst);
	cudaFree(d_src);
	cudaFree(d_dst);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三种基于CUDA的归约计算 的相关文章

  • 3D 数组作为纹理在 CUDA 中写入和读取

    由于我正在编程的算法的性质 我需要用一些特定的数学写入 填充 3D 矩阵 然后从该矩阵 在单独的内核中 读取作为 3D 线性插值纹理 由于纹理是一种读取模式 我假设我可以以某种方式在绑定到纹理的全局内存中写入 并从中单独读取 而不需要双倍内
  • 有关 CUDA 中统一虚拟寻址 (UVA) 的信息/示例

    我试图理解 CUDA 中统一虚拟寻址 UVA 的概念 我有两个问题 是否有任何示例 伪 代码可以演示这个概念 我在 CUDA C 编程指南中读到 UVA 只能在 64 位操作系统上使用 为什么会这样呢 A 统一虚拟地址空间 http doc
  • 卸载使用 CUDA 内存的 mex 文件时 MATLAB 崩溃

    我已经尝试解决这个问题有一段时间了 我在使用 CUDA 的 matlab Linux 64 位 中使用 MEX 文件 代码编译并执行得很好 但是当我想卸载 mex 时 例如重新编译它或当 matlab 退出时 matlab 立即崩溃 没有任
  • VS2010编译器和cuda错误:链接规范与以前的“hypot”不兼容

    当我尝试在 64 位 Windows 7 上使用 VS 2010 在调试 64 位配置中构建我的项目时 我收到此错误以及其他两个错误 错误 链接规范与 math h 第 161 行中先前的 hypot 不兼容 错误 链接规范与 math h
  • NVIDIA GPU 的 CUDA 核心和 OpenCL 计算单元之间有什么关系?

    我的电脑有一块 GeForce GTX 960M NVIDIA 声称它有 640 个 CUDA 核心 然而 当我运行 clGetDeviceInfo 来查找计算机中的计算单元数量时 它打印出 5 见下图 听起来 CUDA 核心与 OpenC
  • CUDA 标量和 SIMD 视频指令的效率

    SIMD指令的吞吐量低于32位整数运算 如果是 SM2 0 仅标量指令版本 则低 2 倍 如果是 SM3 0 则低 6 倍 什么情况下适合使用它们 如果您的数据已经以 SIMD 视频指令本机处理的格式打包 则需要多个步骤对其进行解包 以便可
  • 如何使用 eclipse Nsight 仅使用一个 GPU 调试 CUDA

    我收到错误 所有 cuda 设备均用于显示 在调试时无法使用 使用Ubuntu 有没有什么方法可以使用 Nsight eclipse 仅使用一个 GPU 进行调试 我见过类似的解决方案 sudo 服务 lightdm 停止 杀死 X 但这也
  • 如何隐藏 NVCC 的“函数已声明但从未引用”警告?

    当编译使用Google Test的CUDA程序时 nvcc将发出误报警告 函数 已声明但从未被引用 An MCVE test cu include
  • GPU 上非原子写入的保证很弱吗?

    OpenCL 和 CUDA 包含原子操作已有好几年了 尽管显然并非每个 CUDA 或 OpenCL 设备都支持这些操作 但是 我的问题是关于由于非原子写入而 共存 种族的可能性 假设网格中的多个线程都写入全局内存中的同一位置 我们是否可以保
  • 在 Windows 上的 Qt Creator 中编译 Cuda 代码

    几天来我一直在尝试获取在 32 位 Windows 7 系统上运行的 Qt 项目文件 我希望 需要在其中包含 Cuda 代码 这种组合要么非常简单 以至于没有人愿意在网上放一个例子 要么非常困难 似乎没有人成功 不管怎样 我发现的唯一有用的
  • Ramda 循环数组

    循环可能是错误的术语 但它描述了我正在尝试的事情 我想为平面数据提供结构 但我还需要跟踪它来自的数组 基本上我的规则是 每个数组 如果级别 1 存在 给它name该项目的 以及typechild大批 每次出现级别 1 时 即使在同一个数组中
  • 在Python中结合reduce和map的最简洁的方法

    我正在做一些深度学习 我想获取所有隐藏层的值 所以我最终编写了这样的函数 def forward pass x ws bs activations u x for w b in zip ws bs u np maximum 0 u dot
  • Hadoop:Reducer 将 Mapper 输出写入输出文件

    我遇到了一个非常非常奇怪的问题 减速器确实可以工作 但是如果我检查输出文件 我只找到了映射器的输出 当我尝试调试时 在将映射器的输出值类型从 Longwritable 更改为 Text 后 我 发现字数示例存在相同的问题 package o
  • 为什么GK110有192个核心和4个扭曲?

    我想感受一下开普勒的架构 但这对我来说没有意义 如果一个 warp 有 32 个线程 其中 4 个被调度 执行 则意味着 128 个核心正在使用 64 个核心处于空闲状态 白皮书中提到了独立指令 那么64核是为这些指令保留的吗 如果是这样
  • 将 GPUJPEG 项目移植到 Windows

    我目前正在尝试移植 GPUJPEG 在 Sourceforge 上 http sourceforge net projects gpujpeg 库 基于 CUDA 从 Unix 到 Windows 现在我被卡住了 我不知道发生了什么或为什么
  • CUDA:如何检查计算能力是否正确?

    使用较高计算能力编译的 CUDA 代码将在计算能力较低的设备上完美执行很长一段时间 然后有一天在某些内核中默默地失败 我花了半天时间追寻一个难以捉摸的错误 结果发现构建规则已经sm 21而该设备 Tesla C2050 是2 0 是否有任何
  • 某些子网格未使用 CUDA 动态并行执行

    我正在尝试 CUDA 5 0 GTK 110 中的新动态并行功能 我遇到了一个奇怪的行为 即我的程序没有返回某些配置的预期结果 不仅是意外的 而且每次启动都会出现不同的结果 现在我想我找到了问题的根源 似乎当生成太多子网格时 某些子网格 由
  • libstdc++.so.6 与 cuda 相关的链接器问题

    今天我在链接我编译的 cuda 内容时遇到了问题 我有一个最新的 debian 测试 w 2 6 32 3 amd64 我整天都在写我的代码 不时编译 没有问题 但在进行了较小的代码更改后 我收到以下错误 gcc o pa CUDA o h
  • cudaMallocManaged() 返回“不支持的操作”

    在 CUDA 6 0 中尝试托管内存给了我operation not supported打电话时cudaMallocManaged include cuda runtime h include
  • 在 cuda 的 nvcc 编译器中使用 C++20

    我正在尝试使用std countr zero 函数从

随机推荐

  • Linux设备上时间不准确?使用chrony服务配置时间服务器实现Linux时间同步以及实现主从设备时间同步

    本文基于Linux上CentOS 7版本配合chrony 需要使用yum自行下载 进行演示 目录 一 计算机设备上的两种时间 1 硬件时间 2 系统时间 二 配置同步时间服务器 1 安装服务 2 配置服务 三 搭建主从时间服务器 1 服务器
  • 阿里云提示ECS服务器存在漏洞处理方法

    1 阿里云提供生成修复命令 但是这个只提供给企业版 即收费的 2 自己手动修复的话 采用软件升级一般都可以解决 除了提示带kernel的高危漏洞的 其他的不需要重启实例即可修复 有kernel的需要更新完成重启实例 这里可以先把 漏洞名称
  • 2021-04-08 使用Eclipse进行Web前端开发

    使用Eclipse进行Web前端开发 前言 本机为微软Surface pro4 为64位 所用操作系统为Windos 10 使用的Java版本为1 8 0 151 使用的JDK版本为JDK8 注意事项 1 Eclipse安装插件的时候一定要
  • 【mac】Mac 安装 RabbitMQ

    文章目录 1 概述 2 安装brew 3 安装 4 安装RabiitMQ的可视化监控插件 5 配置环境变量 6 后台启动 rabbitMQ 7 创建rabbitmq账号 8 给账号配置角色 1 概述 学习spring cloud 的时候 因
  • 【pytorch】pytorch模型保存技巧

    Pytorch会把模型相关信息保存为一个字典结构的数据 以用于继续训练或者推理 1 保存与加载模型参数 这是最常见的模型保存与加载方式 保存方式如下 state model state dict torch save state xxx p
  • qml实现红绿灯切换功能

    题目要求 参考代码 https download csdn net download y478225902 5260541 实现源码 import QtQuick 2 12 import QtQuick Window 2 12 Window
  • springboot整合maven Profile实现properties文件多环境配置

    步骤 首先写几个properties的配置文件 一般这样的文件有三个 而且文件的名称也也可以随意 不论你们的项目是使用的springmvc还是springboot 文件名称都可以随意指定 例如我的几个文件 在文件中写一些测试的属性值 方便测
  • 【一】重温HTML

    引言 经典对答 面试官 你了解HTML吗 回答 啊 我是来面试前端的呀 我会Vue 面试官 写文思考 写这一系列文章的时候 自己思考了几个问题 HTML的文章太多了 为什么还要写 HTML的入门谁不会 还要学 HTML的文章基本都是水文 谁
  • ES6解构赋值

    前面的话 我们经常定义许多对象和数组 然后有组织地从中提取相关的信息片段 在ES6中添加了可以简化这种任务的新特性 解构 解构是一种打破数据结构 将其拆分为更小部分的过程 本文将详细介绍ES6解构赋值 引入 在ES5中 开发者们为了从对象和
  • Mysql中MVCC的使用及原理详解

    准备 测试环境 Mysql 5 7 20 log 数据库默认隔离级别 RR Repeatable Read 可重复读 MVCC主要适用于Mysql的RC RR隔离级别 创建一张存储引擎为testmvcc的表 sql为 CREATE TABL
  • error compiling template但编辑器内未报错,处理步骤。

    1 首先寻找自己所引入的组件当中 例如用到了某个方法 而自己没有把方法写上 2 寻找自己所引入的代码当中是否有重复的代码 可能是复制的时候多复制一行而导致的 3 寻找是否有空格所导致的error compiling template 报错
  • 到处是“坑”的strtok()—解读strtok()的隐含特性

    在用C C 实现字符串处理逻辑时 strtok函数的使用非常广泛 其主要作用是按照给定的字符集分隔字符串 并返回各子字符串 由于该函数的使用有诸多限制 如果使用不当就会造成很多 坑 因此本文首先介绍那些经常误踩的坑 然后通过分析源代码 解读
  • Android——第三方Facebook授权登录获取用户信息

    由于项目中需要使用Facebook进行一键登录 所以记录下步骤 其实小伙伴直接看官网也可以 介绍的蛮详细的 先看下效果图吧 遵循以下步骤将Facebook登录添加到您的应用 Facebook开发者网站 https developers fa
  • bin文件转成C语言数组之c代码

    反汇编的时候用的着 include
  • Js弹出showModalDialog窗口---返回值或数组

    function showMyModalDialog url width height showModalDialog url dialogWidth width px dialogHeight height px center yes s
  • ACwing :01背包问题

    朴素的 动规的 基本表示 f i j 表示只看前 i 个物品 总体积是 j 的情况下 总价值最大是多少 result max f n 0 V f i j 1 不选第 i 个物品 f i j f i 1 j 2 选第 i个物品 f i j f
  • ubuntu 如何使用 root 用户

    环境 virtual box 6 1 ubuntu 1604 LTS 64 问题 一般的ubuntu会创建一个管理员用户 在使用 su 指令从管理员切换到root用户后 设在 etc profile的环境变量丢失 如何才能保证环境变量不变呢
  • Android开发中怎么实现上传图片到服务器

    要实现在Android开发中上传图片到服务器 可以按照以下步骤进行 1 在Android项目中添加相应的权限 确保应用程序可以访问设备上的照片或相机 在 AndroidManifest xml 文件中添加以下权限
  • linux服务端下的c++ udp socket demo

    linux服务端 udp socket demo 如下 创建接受数据的socket int iSock socket PF INET SOCK DGRAM 0 printf socket ss d n iSock struct sockad
  • 三种基于CUDA的归约计算

    归约在并行计算中很常见 并且在实现上具有一定的套路 本文分别基于三种机制 Intrinsic 共享内存 atomic 实现三个版本的归约操作 完成一个warp 32 大小的整数数组的归约求和计算 Intrinsic版本 基于Intrinsi