gpt4 book ai didi

c++ - 使用 Thrust 进行流压实;最佳实践和最快的方法?

转载 作者:搜寻专家 更新时间:2023-10-31 02:22:06 26 4
gpt4 key购买 nike

我有兴趣移植一些现有代码以使用推力,看看我是否可以相对轻松地在 GPU 上加速它。

我想要完成的是一个流压缩操作,其中只保留非零元素。根据下面的示例代码,我大部分时间都在工作。我不确定如何处理的部分是在压缩发生后处理 d_res 和 h_res 中的所有额外填充空间。

该示例仅使用 0-99 序列,所有偶数项都设置为零。这只是一个例子,真正的问题是一般的稀疏数组。

这里的答案对我帮助很大,尽管在读取数据时,已知大小是恒定的: How to quickly compact a sparse array with CUDA C?

我怀疑我可以通过计算 d_src 中 0 的数量来解决这个问题,然后只将 d_res 分配为那个大小,或者在压缩之后进行计数,并且只复制那么多元素。这真的是正确的做法吗?

我觉得通过巧妙地使用迭代器或 thrust 的其他一些特性,可以很容易地解决这个问题。

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

//Predicate functor
struct is_not_zero
{
__host__ __device__
bool operator()(const int x)
{
return (x != 0);
}
};

using namespace std;

int main(void)
{
size_t N = 100;

//Host Vector
thrust::host_vector<int> h_src(N);

//Fill with some zero and some nonzero data, as an example
for (int i = 0; i < N; i++){
if (i % 2 == 0){
h_src[i] = 0;
}
else{
h_src[i] = i;
}
}

//Print out source data
cout << "Source:" << endl;

for (int i = 0; i < N; i++){
cout << h_src[i] << " ";
}
cout << endl;

//copies to device
thrust::device_vector<int> d_src = h_src;

//Result vector
thrust::device_vector<int> d_res(d_src.size());

//Copy non-zero elements from d_src to d_res
thrust::copy_if(d_src.begin(), d_src.end(), d_res.begin(), is_not_zero());

//Copy back to host
thrust::host_vector<int> h_res(d_res.begin(), d_res.end());
//thrust::host_vector<int> h_res = d_res; //Or just this?

//Show results
cout << "h_res size is " << h_res.size() << endl;
cout << "Result after remove:" << endl;

for (int i = 0; i < h_res.size(); i++){
cout << h_res[i] << " ";
}
cout << endl;

return 0;
}

另外,我是推力的新手,所以如果上面的代码有任何明显的缺陷,不符合使用推力的推荐做法,请告诉我。

同样,速度总是令人感兴趣的。阅读一些各种推力教程,这里似乎没有什么变化,可能会大大节省速度或浪费速度。所以,请告诉我是否有加快速度的聪明方法。

最佳答案

您似乎忽略了 copy_if 返回一个迭代器,该迭代器指向从流压缩操作复制的数据的末尾。所以只需要这样:

//copies to device
thrust::device_vector<int> d_src = h_src;

//Result vector
thrust::device_vector<int> d_res(d_src.size());

//Copy non-zero elements from d_src to d_res
auto result_end = thrust::copy_if(d_src.begin(), d_src.end(), d_res.begin(), is_not_zero());

//Copy back to host
thrust::host_vector<int> h_res(d_res.begin(), result_end);

这样做会调整 h_res 的大小,使其仅保留非零值,并且仅从流压缩的输出中复制非零值。不需要额外的计算。

关于c++ - 使用 Thrust 进行流压实;最佳实践和最快的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30691363/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com