CUDA 进阶编程 Thrust库使用-vector

2 篇文章 0 订阅

Thrust库的介绍

thrust是NVIDIA推出的一个高性能的GPU版本并行开发库,thrust提供了丰富的算法和容器, 我们可以使用这些工具来简化我们的编程

thrust的库的API都是STL like的, 对于STL比较熟悉的人学习起来会比较简单, 当然thrust库提供了很多C++11和C++17 风格的接口,如果对于C++11 和 C++17 不熟悉的人学习起来还是有点吃力,推荐在学习thrust库前先把C++11 和 C++17的库学习下, thrust库提供的不过都是这些接口的并行版本

C++参考网页

thrust库虽然提供了高性能的接口,帮我们简化了很多代码,但是本质上还是依赖于CUDA的底层那套机制,无非是cudaMemcpy之类的, 所以在实际项目中,推荐还是要会这一套接口, 否则在使用的过程中, 但是很容易写出低效的版本

Vector

vector是thrust最基础也是最简单的容易,分为host_vector和device_vector
host_vector就是指在CPU和内存里面的数据
device_vector就是指GPU里面的数据
vector提供iterator进行遍历等操作, 所有thrust的容器都支持迭代器

简单示例

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

#include <iostream>

int main(void)
{
    thrust::host_vector<int> H(4);

    // 初始化host_vector
    H[0] = 14;
    H[1] = 20;
    H[2] = 38;
    H[3] = 46;
    std::cout << "H has size " << H.size() << std::endl;

    for(int i = 0; i < H.size(); i++)
        std::cout << "H[" << i << "] = " << H[i] << std::endl;

    // 将host的数据拷贝到device上面
    thrust::device_vector<int> D = H;
    
    D[0] = 99;
    D[1] = 88;
    
    for(int i = 0; i < D.size(); i++)
        std::cout << "D[" << i << "] = " << D[i] << std::endl;
        
    return 0;
}

上面只是一个简单的示例, 可以看到基本跟我们使用STL的vector差不多, 但是内部实现不同

底层实现

代码
上面的图片是跑了示例后用Nsight查看的结果, 可以看到vector还是使用cudaMalloc和cudaMemcpyAsync来进行操作的, 所以在使用这些库之前,还是要先了解下这些函数

使用技巧

利用vector传输数据

之前自己用CUDA传输数据的时候,都要用cudaMalloc和cudaMemcpy, cudaFree等一系列函数, 非常麻烦,使用vector后, 可以简化这些数据的传输

 thrust::device_vector<int> D = H;
 thrust::device_ptr<int> p = D.data();
不要一个个的复制数据
    D[0] = H[0];
    D[1] = H[1];

这段代码如果在之前的STL是没问题的,数据量少的时候也没问题, 但是因为D是device_vecto, 开辟的是显存,H是host_vector, 开辟的是内存, 这里将会触发2次内存拷贝, 在数据量多的时候,效率会非常低, 非常不建议这样内存, 建议内存还是一次性拷贝好, 直接调用 = 就只会调用一次

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
是的,thrust中的device_vector不支持使用push_back函数。这是因为在GPU上,需要使用连续的内存来存储数据,而push_back会导致内存重新分配和复制,从而破坏了内存的连续性。 相反,可以使用thrust中的push_back_iterator来将数据添加到device_vector中。使用push_back_iterator时,需要先创建一个迭代器对象,然后将其传递给thrust的算法函数,该函数将在迭代器指向的位置插入新的元素。 以下是一个使用push_back_iterator的示例代码: ```c++ #include <thrust/device_vector.h> #include <thrust/copy.h> #include <thrust/iterator/constant_iterator.h> #include <thrust/iterator/counting_iterator.h> #include <thrust/iterator/permutation_iterator.h> #include <iostream> int main() { thrust::device_vector<int> vec(5, 1); thrust::counting_iterator<int> first(10); thrust::counting_iterator<int> last = first + 5; thrust::copy(first, last, thrust::make_permutation_iterator(vec.begin(), vec.begin() + 2)); // print the contents of vec std::cout << "vec: "; thrust::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; return 0; } ``` 在这个例子中,我们使用thrust::make_permutation_iterator函数创建了一个迭代器对象,该对象使用了vec.begin()和vec.begin() + 2作为参数,该迭代器可以插入新的元素。然后,我们使用thrust::copy函数将从first到last的元素复制到vec中,使用了创建的迭代器来指定插入位置。 希望这个回答可以帮助到你。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值