cuda trust 库的使用

1 研究cuda编程一个月了,对于cuda的运行机制也基本上是了解了,有时候加速是必须的,但是有时候程序设计的不好,加速就起不到作用,特备是共享内存设计的时候,如果没有让数据一直处于重复利用的状态,那么加速是没有效果的, 所以我觉得就是只有数据需要连续重复使用的时候放在共享内存里面才是真正的加快速度,之前的关于cuda的一些基本的机制也都有介绍过,软件硬件都有设及,现在发现了cuda有一个比较好用的库,可以操作向量,进行矩阵转置,矩阵相加,速度非常快,并可以直接调用host端的数据,已经封装好了数据到显存的copy操作和显存到host的操作
2 山重水复疑无路啊,我想了很多的办法,加快这个排序,刚开始就去网上找多线程gpu排序,有不少的程序,但是这些程序都是偶bug的,最有名的就是cuda双调排序,一次就只能进行一个块的排序,所以,我就自己去找程序,发现在cuda样例里面也有快速排序的版本,速度很快,基本上500万的数据只需要用36毫秒。但是这个程序有500多行,并且啊,这个数据是随机生成的,很难替换成自己的数据
3,在偶然中,发现了cuda还有自己自带的trust库,这个库可以实现很多的功能,简直不要太方便。
thrust是并行算法和数据结构的基于GPU CUDA的C++库。Thrust主要通过管理系统底层的功能比如memory access(内存获取)和memory allocation(内存分配)来实现加速,使得工程师们在GPU编程的环境下能更focus在算法的设计上。
第一个叫做向量
二、Vectors
vector是C++标准程序库(STL)中的一个类。C++ STL中也有例如std::vector的vector容器(container)。Thrust中提供了两种vector container:host_vector和device_vector。host_vector会存储在host memory中而device_vector会存储在GPU device memory中。
以下来自NVIDIA CUDA官网的例子阐释了如何使用vector containers:

#include #include #include int main(void) { // H has storage for 4 integers thrust::host_vector H(4); // initialize individual elements H[0] = 14; H[1] = 20; H[2] = 38; H[3] = 46; // H.size() returns the size of vector H std::cout << "H has size " << H.size() << std::endl; // print contents of H for(int i = 0; i < H.size(); i++) std::cout << "H[" << i << "] = " << H[i] << std::endl; // resize H H.resize(2); std::cout << "H now has size " << H.size() << std::endl; // Copy host_vector H to device_vector D thrust::device_vector D = H; // elements of D can be modified D[0] = 99; D[1] = 88; // print contents of D for(int i = 0; i < D.size(); i++) std::cout << "D[" << i << "] = " << D[i] << std::endl; // H and D are automatically deleted when the function returns return 0; }

算法
Thrust提供了很多的并行算法。例如thrust::sort。Thrust中的所有算法都会有host何device的版本。唯一例外的就是thrust::copy函数,它的所有iterator arguments都应该在同一个地方:要么都在host上要么都在device上。
以thrust::sort举例说明:
对于一个数组进行排序,只需一个指令即可达成:

#include ... const int N = 6; int A[N] = {1, 4, 2, 8, 5, 7}; thrust::sort(A, A + N); // A is now {1, 2, 4, 5, 7, 8}

当调用Thrust中的函数时,将根据迭代器的类型选择使用主机端还是设备端的算法实现。因为主机/设备调度是在编译时解析,所以这一过程被称为静态调度。这意味着在运行时没有额外的调度进程。
你可能想知道当raw指针作为Thrust函数的参数会如何。和STL一样,Thrust允许这种用法,并调度主机端的算法实现。如果传入的指针是指向设备端内存的指针,那么在调用函数之前需要用thrust::device_ptr封装。例如:
#include #include #include int main(void) { size_t N = 10; // obtain raw pointer to device memory int * raw_ptr; cudaMalloc((void **) &raw_ptr, N * sizeof(int)); // wrap raw pointer with a device_ptr thrust::device_ptr dev_ptr = thrust::device_pointer_cast(raw_ptr); // use device_ptr in Thrust algorithms thrust::fill(dev_ptr, dev_ptr + N, (int) 0); // access device memory transparently through device_ptr dev_ptr[0] = 1; // free memory cudaFree(raw_ptr); //NOTEcudaMalloc and cudaFreereturn 0; }

如需从device_ptr中提取raw指针,需要使用raw_pointer_cast,用法如下:
#include #include #include #include #include int main(void) { size_t N = 10; // create a device_ptr thrust::device_ptr dev_ptr = thrust::device_malloc(N); // extract raw pointer from device_ptr int * raw_ptr = thrust::raw_pointer_cast(dev_ptr); // use raw_ptr in CUDA API functions cudaMemset(raw_ptr, 0, N * sizeof(int)); // free memory thrust::device_free(dev_ptr); //NOTE device_malloc and device_free// we can use the same approach for device_vector thrust::device_vector d_vec(N); // note: d_vec.data() returns a device_ptr raw_ptr = thrust::raw_pointer_cast(d_vec.data()); //NOTE or (&d_vec[0])return 0; }

【cuda trust 库的使用】

    推荐阅读