CUDA计算直方图(一)原子操作 atomicAdd

2023-11-07

参考: Shane Cook. CUDA Programming: A developer’s guide to parallel computing with GPUs

背景

计算直方图是图像处理和机器学习等常用的操作.
对于大数据集, 使用串行算法十分浪费时间.
这里使用CUDA来加速直方图的计算.
对于一个较大的整数数组, 值域0~255. 求取直方图.

使用CPU计算

void cpuHist(Cuda8u *pHist_data, Cuda32u* pBin_data, Cuda32u arraySize, Cuda32u binSize)
{
	for (Cuda32u i = 0; i < arraySize;i++)
	{
		if (pHist_data[i] < binSize)
		{
			pBin_data[pHist_data[i]]++;
		}
	}

}

main函数调用:

	// CPU 数据初始化
    const Cuda32u uArraySize = 256*256;
	const Cuda32u uBinSize = 256;
	Cuda8u *h_puchData = (Cuda8u *)malloc(uArraySize*sizeof(Cuda8u));
	for (int i = 0; i < uArraySize; i++)
	{
		h_puchData[i] = rand() % uBinSize;
	}
	Cuda32u h_puHist[uBinSize] = { 0 };
	Cuda32u N = 64;
	Cuda32u iIterNum = 10;
	// 使用CPU计算
	StartTimer();
	for (Cuda32u i = 0; i < iIterNum;i++)
	{
		cpuHist(h_puchData, h_puHist, uArraySize, uBinSize);
	}
	double dblTimeElps = GetTimer();
	Cuda32u iSumC = 0;
	for (Cuda32u i = 0; i < uBinSize; i++)
	{
		iSumC += h_puHist[i];
	}
	printf("\n%%%%%%%%%%%%%% CPU 计算直方图:%%%%%%%%%%%%%%\n");
	printf("序列长度 = %d\n", uArraySize);
	printf("重复次数 = %d\n", iIterNum);
	printf("Hist累计 = %d\n", iSumC / iIterNum);
	printf("平均用时 = %fms\n", dblTimeElps / (Cuda64f)iIterNum);
	printf("%%%%%%%%%%%%%% CPU 计算直方图:%%%%%%%%%%%%%%\n");

使用CUDA 原子操作atomicAdd

__global__ void myhistogram256Kernel_01(const Cuda8u *d_hist_data, Cuda32u *d_bin_data)
{
	const Cuda32u idx = blockIdx.x*blockDim.x + threadIdx.x;
	const Cuda32u idy = blockIdx.y*blockDim.y + threadIdx.y;
	const Cuda32u tid = idx + idy*blockDim.x*gridDim.x;

	const Cuda8u value = d_hist_data[tid];
	atomicAdd(&(d_bin_data[value]), 1);

}
void cudaHist_01(Cuda8u* d_puchData, Cuda32u *d_puHist)
{
	// 总的thread数量要和数组长度相同.
	dim3 thread_rect(16, 16);
	dim3 block_rect(16, 16);
	myhistogram256Kernel_01 << <block_rect, thread_rect >> >(d_puchData, d_puHist);
}

main函数调用:

	// 先将CPU里的数据搬移到GPU中!
	memset((void*)h_puHist, 0, uBinSize*sizeof(Cuda32u));
	Cuda8u * d_puchData = NULL;
	Cuda32u * d_puHist = NULL;
	checkCudaErrors(cudaMalloc((void**)&d_puchData, uArraySize*sizeof(Cuda8u)));
	checkCudaErrors(cudaMalloc((void**)&d_puHist, uBinSize*sizeof(Cuda32u)));
	checkCudaErrors(cudaMemcpy((void*)d_puchData, (void*)h_puchData, uArraySize*sizeof(Cuda8u), cudaMemcpyHostToDevice));
	checkCudaErrors(cudaMemcpy((void*)d_puHist, (void*)h_puHist, uBinSize*sizeof(Cuda32u), cudaMemcpyHostToDevice));
	// 预热
	cudaAdd();
	// 开始计时
	cudaEvent_t start, stop;
	Cuda32f elapsedTime = 0.0;
	cudaEventCreate(&start);
	cudaEventCreate(&stop);
	cudaEventRecord(start, 0);
	for (Cuda32u i = 0; i < iIterNum;i++)
	{
		// 求直方图
		//cudaHist_07((Cuda32u*)d_puchData, d_puHist, N);
		cudaHist_01(d_puchData, d_puHist);
	}
	// 结束计时
	cudaEventRecord(stop, 0);
	cudaEventSynchronize(stop);
	cudaEventElapsedTime(&elapsedTime, start, stop);
	cudaEventDestroy(start);
	cudaEventDestroy(stop);
	// 将GPU内的数据拷回CPU
	checkCudaErrors(cudaMemcpy((void*)h_puHist, (void*)d_puHist, uBinSize*sizeof(Cuda32u), cudaMemcpyDeviceToHost));
	iSumC = 0;
	for (Cuda32u i = 0; i < uBinSize; i++)
	{
		iSumC += h_puHist[i];
	}
	printf("\n%%%%%%%%%%%%%% CUDA 计算直方图:%%%%%%%%%%%%%%\n");
	printf("序列长度 = %d\n", uArraySize);
	printf("重复次数 = %d\n", iIterNum);
	printf("Hist累计 = %d\n", iSumC / iIterNum);
	printf("平均用时 = %f ms\n", elapsedTime / (Cuda32u)iIterNum);
	printf("%%%%%%%%%%%%%% CUDA 计算直方图:%%%%%%%%%%%%%%\n\n");
	// 释放资源
	checkCudaErrors(cudaFree((void*)d_puchData));
	checkCudaErrors(cudaFree((void*)d_puHist));

	cudaDeviceReset();

运行结果:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CUDA计算直方图(一)原子操作 atomicAdd 的相关文章

随机推荐

  • Mac系统创建python3.7虚拟环境

    mac系统python3 7安装虚拟环境 什么叫虚拟环境呢 python特有的一种软件环境 创建多个python环境 各个环境之间完全隔离 互不影响 它可以用来解决Python项目开发和运行过程中的依赖项和版本问题 而不必和其他项目的Pyt
  • dfs找不到网络路径 windows_DFS 复制服务已启动位于本地路径 C:\WINDOWS\SYSVOL\domain 上的 SYSVOL,并正在...

    公司新建域控由于分公司需要辅助域控 就新建了一台额外域控 但是该域控建好后发现组策略不生效 检查sysvol文件夹一片空白 肯定是没有从主域控复制过来 使用dcdiag检查 有下面报错 目录服务器诊断 正在执行初始化设置 正在尝试查找主服务
  • Android -- Activity and Intent

    Android Activity and Intent Activity Activity Lifecycle Intent 显式Intent 隐式Intent Intent属性 Intent Examples Activity activ
  • OpenCV计算机视觉学习(3)——图像灰度线性变换与非线性变换(对数变换,伽马变换)

    人工智能学习离不开实践的验证 推荐大家可以多在FlyAI AI竞赛服务平台多参加训练和竞赛 以此来提升自己的能力 FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台 每周免费提供项目开源算法样例 支持算法能力变现以及快
  • 阿里云 日志服务接入

    目前项目中都有用到日志记录 一般会存到本地 但是时间长了 去删除也是很麻烦的 阿里云日志服务 是个不错的选择 可分为两种 自动采集和自动上传到云 1 写文件到本地 然后配置 让阿里云自动采集 LogHub 支持客户端 网页 协议 SDK A
  • JVM垃圾收集器总结

    JVM的垃圾收集算法 最终是要由垃圾收集器实现的 不同厂商 不同版本的虚拟机的垃圾收集器实现差别很大 本文只介绍HotSpot中的垃圾收集器 包括 串行收集器 并行收集器 新生代Parallel Scavenge收集器 CMS G1 一 整
  • FLOYD算法

    1 定义概览 Floyd Warshall算法 Floyd Warshall algorithm 是解决任意两点间的最短路径的一种算法 可以正确处理有向图或负权的最短路径问题 同时也被用于计算有向图的传递闭包 Floyd Warshall算
  • 开启IIS,“出现错误,并非所有功能被成功更改”

    环境 Windows7 Ultimate 事件 测试需要 要在自己的计算机上搭建临时IIS 在打开或关闭windows功能里 开启了相关组件及功能 确定应用后提示 出现错误 并非所有功能被成功更改 解决 网上查阅相关资料后 众说纷纭 后来在
  • Java将一段逗号分割的字符串转换成一个数组(亲测)

    String 类 String 类代表字符串 Java 程序中的所有字符串字面值都作为此类的实例实现 字符串是常量 它们的值在创建之后不能更改 字符串缓冲区支持可变的字符串 因为 String 对象是不可变的 所以 可以共享 String
  • 关于命令行中不能运行pip程序和python程序

    大多数都是没有将pip程序和python程序下载的路径添加到环境变量 1 添加pip的环境变量 2 添加pythn的环境变量 小心不要添加成了python快捷方式的环境变量 我一开始就添加的是python快捷方式的变量 结果一直以为是添加的
  • checkbox的value和checked属性详解

    一 checked属性 checked属性代表的是当前checkbox是否被选中 如果选中返回true 未选中返回false 和value值无关 p p
  • hive环境配置

    记录一下hive环境 Mac m1 的配置过程 以防忘记 可能遇到的问题 1 安装hadoop 1 首先 安装hadoop brew install Hadoop arch x86 64 brew install Hadoop for M1
  • Pycharm安装教程

    个人简介 作者简介 大家好 我是W chuanqi 一个编程爱好者 个人主页 W chaunqi 支持我 点赞 收藏 留言 愿你我共勉 若身在泥潭 心也在泥潭 则满眼望去均是泥潭 若身在泥潭 而心系鲲鹏 则能见九万里天地 文章目录 Pych
  • python笔记10--pyinstaller打包源码

    python笔记10 pyinstaller打包源码 1 介绍 2 用法 3 常见问题 4 说明 1 介绍 本文主要介绍使用pyinstaller打包py脚本为可执行程序 后续会在此处续更其它复杂案例 2 用法 安装 由于当前主流使用py3
  • MES管理系统:实现两化融合的关键业务融合点

    随着中国经济的快速发展 两化融合已成为推动企业转型升级的重要手段 在这个过程中 MES作为面向生产级的管理系统 扮演着至关重要的角色 本文将探讨MES生产管理系统如何实现业务融合 并为企业带来丰厚的经济效益 首先 让我们回顾一下MES系统的
  • 面试官:你在xx项目中有哪些亮点或是贡献亦或是小技巧?

    前言 面试官 你在xx项目中有哪些亮点或是贡献亦或是小技巧 我 阿巴阿巴 卡 停一下 你是不是也有相同或者类似的经历 实际大部分同学们多数情况下都是在使用vue或react去实现业务代码 跟业务代码打交道比较多 每当面试官一问起 还真是说不
  • Qt removeOne函数解析

    如下 使用removeOne是否会导致空指针呢 include
  • Google Play 上架总结(二)Google账户关联详解

    近期 本人在 App 上架Google Play 过程中 频繁遇到账号被关联封禁 在踩过很多坑后 我觉得有必要总结一下 给其它朋友作为参考 一 Google 账户关联是指什么 账户关联是就是当Google开发者账号因为各种原因被封停了 此时
  • 从哈佛1000多页的课程名单里,我看到了何谓“大学”

    从哈佛1000多页的课程名单里 我看到了何谓 大学 2017 02 24 22 11 39 来源 齐鲁壹点 山东 举报 分享到 易信 微信 QQ空间 微博 原标题 从哈佛1000多页的课程名单里 我看到了何谓 大学 我相信 大学精神的本质
  • CUDA计算直方图(一)原子操作 atomicAdd

    参考 Shane Cook CUDA Programming A developer s guide to parallel computing with GPUs 目录 背景 使用CPU计算 使用CUDA 原子操作atomicAdd 背景