【无标题】

CUDA中thrust库的使用

CUDA中thrust库的使用

    接触过CUDA的各位应该都了解过归约算法,包括归约算法求和、求最大最小值、求方差标准差等等。为了保证算法的时间复杂度,我们常常会花费大量的时间去优化归约算法的实现,包括线程分散度的问题、thread分歧以及bank冲突的问题等等。当数据维度较小时还能够冷静的分析每一个可能还存在优化空间的点,但当数据维度较大时,常常感觉优化的程度还是不够。不要慌,这时就是体现CUDA强大的时刻,CUDA的thrust库可以完美的解决这些问题。
    本文主要记录一下最近使用到的thrust库中的函数,包括reduce、sort、unique等等。

1、vector

    在记录函数之前,首先记录一下thrust提供的数据类型vector,thrust中定义了host端和device端的两种vector,分别定义在host_vector.hdevice_vector.h中,在声明变量时也很简单:

thrust::host_vector<type> hvec;
thrust::device_vector<type> dvec;
dvec=hvec; //device vector和 host vector可以直接用等号进行传递,对应于cudaMemcpy的功能

      
      
  • 1
  • 2
  • 3

    thrust中还定义了device_ptr指针类型,当传入函数的指针是指向device端的内存时,需要用device_ptr进行封装:

float array[6] = { 3, 1, 2, 3, 5, 4 };
float *dev_array = 0;
cudaMalloc(&dev_array, 4 * 6);
cudaMemcpy(dev_array, array, 4 * 6, cudaMemcpyHostToDevice);
thrust::device_ptr<float> dev_ptr(dev_array);
thrust::reduce(dev_ptr, dev_ptr + 6);//由于dev_array指向device端,不能直接作为参数,需要对其封装

thrust::host_vector<type> hvec;
thrust::device_vector<type> dvec;
dvec=hvec;
thrust::reduce(dvec.begin(), dvec.end());//此时的参数是迭代器,不用也不能用device_ptr对其封装

//上述的两种函数的调用方法也存在host端的版本,传入的指针或者迭代器都是host端数据
thrust::reduce(array, array + 6);
thrust::reduce(hvec.begin(), hvec.end());

//从device_ptr中提取“原始”指针需要使用raw_pointer_cast函数
float dev_array=thrust::raw_pointer_cast(dev_ptr);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

    上述程序中说明了thrust中的数据类型以及函数调用时四种调用方式,本文后续函数使用的例子中,一个函数只选取一种调用方式,其余的方式可以类比调用。

2、reduce

    thrust::reduce函数主要用于归约操作,在reduce.h中被定义,其返回值可以为一个具体数值,调用的方式也很简单:

thrust::device_ptr<float> dev_xptr(dev_xvalue);
double sum = thrust::reduce(dev_xptr, dev_xptr + N);

 
 
  • 1
  • 2

    也可以通过thrust::transform_reduce函数,定义自己想要的归约方式,下面的例子定义了一个求方差的归约:

//随意定义想要的归约方式
struct variance: std::unary_function<float, float>
{
	variance(float m): mean(m){ }
	const float mean;
	__host__ __device__ float operator()(float data) const
	{
		return ::pow(data - mean, 2.0f);
	}
};
//需要提前通过reduce函数求和,从而获得均值mean
float variance = thrust::transform_reduce(dev_ptr,dev_ptr + N,variance(mean),0.0f,thrust::plus<float>()) / N;

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3、sort

    sort函数用于对数据的数据进行排序,在sort.h中定义,使用方式也很简单:

int A[6] = {1, 4, 2, 8, 5, 7};
thrust::sort(A, A + 6);
//result:{1, 2, 4, 5, 7, 8} 默认排序方式为由小到大

//sort_by_key函数可以根据键值来进行排序
int keys[N] = { 1, 4, 2, 8, 5, 7};
char values[N] = { ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’};
thrust::sort_by_key(keys, keys + N, values);
//result: key{1, 2, 4, 5, 7, 8}
// values{‘a’, ‘c’, ‘b’, ‘e’, ‘f’, ‘d’}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

    当然sort函数也可以自己定义排序方式,下面的例子是对三维坐标点的坐标值按照由小到大排序:

struct compRule
{
	__host__ __device__
		bool operator()(const float3 &p1,const float3 &p2)
	{
		if (p1.x != p2.x)
			return p1.x <= p2.x;
		else if (p1.y != p2.y)
			return p1.y <= p2.y;
		else if (p1.z != p2.z)
			return p1.z <= p2.z;
<span class="token punctuation">}</span>

};
thrust::host_vector<float3> p(10);
thrust::sort(p.begin(), p.end(), compRule());
//输入 //输出
//p[0] = { 0, 0, 0 }; p[0] = { 0, 0, 0 };
//p[1] = { 0, 1, 0 }; p[1] = { 0, 0, 1 };
//p[2] = { 1, 0, 0 }; p[2] = { 0, 1, 0 };
//p[3] = { 1, 0, 1 }; p[3] = { 0, 1, 1 };
//p[4] = { 1, 1, 1 }; p[4] = { 0, 1, 1 };
//p[5] = { 0, 1, 1 }; p[5] = { 1, 0, 0 };
//p[6] = { 0, 0, 1 }; p[6] = { 1, 0, 1 };
//p[7] = { 1, 1, 0 }; p[7] = { 1, 0, 1 };
//p[8] = { 0, 1, 1 }; p[8] = { 1, 1, 0 };
//p[9] = { 1, 0, 1 }; p[9] = { 1, 1, 1 };

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

    最后还有stable_sort函数,与sort不同的是,其在排序时不改变相同数据的相对位置。

3、max_element(min_element)

    max_element(min_element)函数,故名思义,求最大(小)值,在extrema.h被定义,调用方法如下:

thrust::device_vector<type>::iterator iter = thrust::max_element(dvec.begin(),dvec.end());
//其返回值是一个迭代器
int position = iter - dvec.begin();//获取最大(小)值所在位置
type max_val = *iter; //获取最大(小)值结果

 
 
  • 1
  • 2
  • 3
  • 4

4、unique

    unique函数,用来将一组数据中满足条件的数据筛选出来,在unique.h中被定义,也可以自定义筛选条件。下面例子的功能是删除重复数据:

struct is_sam
{
	__host__ __device__
		bool operator()(const float3 &p1, const float3 &p2)
	{
		return (p1.x==p2.x) && (p1.y==p2.y) && (p1.z==p2.z);
	}
};

thrust::unique(p.begin(), p.end(),is_sam()),p.end();
//unique函数的功能只是将满足条件的数据筛选出来,无法直接删除,需要结合vector的erase函数进行删除
p.erase(thrust::unique(p.begin(), p.end(),is_sam()),p.end());

//输入 //unique后结果 //erase后结果
//p[0] = { 0, 0, 0 } p[0] = { 0, 0, 0 } p[0] = { 0, 0, 0 }
//p[1] = { 0, 0, 1 } p[1] = { 0, 0, 1 } p[1] = { 0, 0, 1 }
//p[2] = { 0, 1, 0 } p[2] = { 0, 1, 0 } p[2] = { 0, 1, 0 }
//p[3] = { 0, 1, 1 } p[3] = { 0, 1, 1 } p[3] = { 0, 1, 1 }
//p[4] = { 0, 1, 1 } p[4] = { 1, 0, 0 } p[4] = { 1, 0, 0 }
//p[5] = { 1, 0, 0 } p[5] = { 1, 0, 1 } p[5] = { 1, 0, 1 }
//p[6] = { 1, 0, 1 } p[6] = { 1, 1, 0 } p[6] = { 1, 1, 0 }
//p[7] = { 1, 0, 1 } p[7] = { 1, 1, 1 } p[7] = { 1, 1, 1 }
//p[8] = { 1, 1, 0 } p[8] = { 0, 1, 1 }
//p[9] = { 1, 1, 1 } p[9] = { 1, 0, 1 }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

    目前只接触了以上函数的使用,后续使用过的其他函数会持续的进行添加!

</article>
还能输入1000个字符
 
表情包 插入表情
表情包 代码片
  • HTML/XML
  • objective-c
  • Ruby
  • PHP
  • C
  • C++
  • JavaScript
  • Python
  • Java
  • CSS
  • SQL
  • 其它
  • <
  • 1
  • >
</div>
相关推荐
Thrust:一个面向效率 CUDA编程
08-20
Thrust并行模板 教程, 使用 Thrust编写应用程序会使得程序简洁、可读性强。
CUDA 进阶编程 Thrust 使用-算法与迭代器
10-07 1566
文章目录device_ptrfor_each, transform, copy等简单算法自定义function与 STL进行配合 device_ptr thrust提供了一个ptr, 叫device_ptr。 但是注意, 这个不是类似auto_ptr, 也不是类似shared_ptr, 只是为了类型安全做 简单 封装,从device_ptr 源码里面,我们没有看到对应 析构代码 size_t N =...
CUDA编程入门--- Thrust 简介_he wolf_ thrust
3-8
Thrust开源 简介是“code at speed of light”。光速代码 实现听上去太过夸张,但是 thrustcuda硬件加速 确实有着无比强大 功能。 Thrust是并行算法和数据结构 基于GPU CUDA C++ Thrust主要通过管理系统底层 功能比如memory acc...
CUDA编程入门---- Thrust 简介
热门推荐
04-12 1万+
一、简介 Thrust开源 简介是“code at speed of light”。光速代码 实现听上去太过夸张,但是 thrustcuda硬件加速 确实有着无比强大 功能。

Thrust是并行算法和数据结构基于GPU CUDAC++Thrust主要通过管理系统底层功能比如memory access(内存获取)和memory allocation(内存分配)来实现加速,使得


cuda thrust
03-16
cuda thrust源码,对学习 thrust很有帮助
thrust 一些源码 cuda vector容器
04-01
cuda容器 可以让你在gpu上像cpu上一样编程
CUDA THRUST介绍
文章目录一、注意事项二、算法(翻译自 thrust文档)1.Searching2.Copying3.Reductions4.Merging2.copying总结

一、注意事项
thrust一般还是只能单独(从host)调用,并不适合和.cu混合使用
thrust算法主要是建立在vector和map<key,value>这两种数据结构之上。
二、算法(翻译自thrust文档)
1.Searching
binary search
lower_bound
upper_bound
2.Copyi


CUDA 进阶编程 Thrust 使用-vector
10-07 2794
文章目录 Thrust 介绍Vector简单示例底层实现 使用技巧利用vector传输数据不要一个个 复制数据 Thrust 介绍 thrust是NVIDIA推出 一个高性能 GPU版本并行开发 , 目 是为了简化 CUDA 编程. thrust提供了丰富 算法和容器, 我们可以 使用这些工具来简化我们 编程 thrust API都是 STL like , 对于 STL比较熟悉 人学习起来会比较简单,...
CUDA Thrust sort 与C++ STL sort速度对比
01-30 3807
1.测试平台:CPU:Intel(R) Xeon(R) CPU E5-2620 v4 @ 2.10GHz       GPU:nvidia tesla p100         memory:32GB       CUDA 9.0     GCC 4.82.试验结果2.1 NVIDIA_ CUDA-9.0_Samples/6_Advanced/radixSort Thrust 1000元素 一百万元素试...
使用 cuda thrust 加速图像翻转
使用 cuda thrust, 实现 RGB 图像,绕 Y 轴翻转。

优点有如下:

  • 速度快,对于 1024 * 1024 图像,大约 0.01 ms,远远小于 CPU 版本时间。
  • 翻转时,不需要额外拷贝时间,使用内存少。

cuda 使用 thrust api求一个向量 最值
懒得自己写了,就 使用thrust api算了。还挺不错。 cuda程序 #incl ude < thrust/extrema.h> #incl ude < thrust/device_ptr.h> #incl ude <io stream>

int main(){

float* deviceArray;
float max, …


CUDA入门知识
Thrust 从C++ STL 得到灵感,将最简单 类似于 STL 结构放在 Thrust ,比如 STL vector。此外, Thrust 还包含 STL 算法和迭代器。          Thrust函数 提供了两个向量容器,分别为主机和设备提供了向量类并且分别驻留在主机和设备 全局内存 。向量可以 使用数组下标进行读取或者修改。然而,如果向量在设备上,那么对于每个这样 访问, Thrust通过PC
动手学习深度学习(Pytorch版)Task 2:文本预处理
02-15 6634
文本预处理 文本是一类序列数据,一篇文章可以看作是字符或单词 序列,文本数据常见 预处理四个步骤如下:

读入文本
分词
建立字典,将每个词映射到一个唯一索引(index)
将文本从词序列转换为索引序列,方便输入模型

读入文本
数据集:英文小说——H. G. WellTime Machine
import collections
import re

def read_time_mach…


cudathrust 进行加速
官方网站 :

https://docs.nvidia.com/cuda/thrust/index.html
https://github.com/NVIDIA/thrust

thrus特点

thrust一般还是只能单独(从host)调用,并不适合和.cu混合使用
thrust算法主要是建立在vector和map<key,value>这两种数据结构之上。 比较适合工程使用,并不能实现复杂算法;
如果你需要处理big sizevector和map,并且操作都比较简单,可以考虑 t


CUDA thrust
11-24 181
CUDA thrust thrust thrust :: sort_by_key thrust::greater/less< float/int >( ) thrust::device_ptr < float> dev_sortval = thrust::device_pointer_ca st(d_sortval) thrust :: stable_sort thrust Thrust是一个类似于 STL 针对 CUDA C++模板 ,能够使程序更简洁易读。 Thrust提供与 CUDA C完全兼容
CUDA开发】 CUDA Thrust 规约求和
1. 使用 Thrust

Thrust 是一个开源 C++ ,用于开发高性能并行应用程序,以 C++ 标准模板为蓝本实现。

官方文档见这里:CUDA Thrust

/* … */
float *fMatrix_Device; // 指向设备显存
int iMatrixSize…


Thrust快速入门教程(三)——算法 2
05-26 5797
<br /><br />Reductions<br />Reduction算法 使用二元操作将输入序列规约为一个单值。例如,需要获得一数列 和,可以通过加运算规约此数组得到。相似 ,数列 最大值,可以通过由两个输入值返回一个最大值 运算子规约得到。数列 求和 规约操作可以由 thrust::reduce如下实现:<br />int sum = thrust :: reduce (D. begin () , D. end () , ( int ) 0, thrust :: pl us <int >()); <br
CUDA 使用 thrust进行排序和注意事项
最新发布
CUDA 进行排序时,如果用自定义 cuda十分耗时,我们选择 cuda自定义函数进行测试,选择 thrust::sort函数,新建文件,命名为sort. cu,代码如下:

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/generate.h>
#include <thrust/sort.h>
#include <thrust/copy.h


CUDA Thrust
10-26 2356
哈哈哈
Thrust快速入门教程(三) —— Algori thms
03-19 5667
Thrust提供了丰富 常用并行算法。这算法 功能与 STL 非常相似。所有 Thrust算法均提供了ho st端(主机端)和device端(设备端) 实现。当传入迭代器指向主机端时,将会调用主机端方法,当 使用迭代器指向设备端时将调用设备端实现。
Thrust快速入门教程(四) —— Fancy Iterators
03-19 2604
高级迭代器可以实现多种有价值功能。本节将展示如何利用高级迭代器和标准 Thrust算法处理一个更广泛 类问题。对于那些熟悉 Boo st C ++ 开发者,他们会发现 Thrust 高级迭代器与Boo st迭代器 非常相似。con stant_iterator  常量迭代器最明显 特点,是每次解引用时,都会返回一个相同 值。下面 例子我们将一个常量迭代器 初始值设置为10。#incl ude < thrust/
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页

最新评论

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值