C++ 逆冲压实;最佳实践和最快方式?

C++ 逆冲压实;最佳实践和最快方式?,c++,cuda,gpgpu,thrust,sparse-array,C++,Cuda,Gpgpu,Thrust,Sparse Array,我感兴趣的是移植一些现有的代码来使用推力,看看我是否可以相对轻松地在GPU上加速它 我希望实现的是流压缩操作,其中只保留非零元素。根据下面的示例代码,我已经基本上实现了这一点。我不确定如何处理的部分是,在压实发生后,处理所有以d_res和h_res表示的额外填充空间 该示例仅使用0-99序列,所有偶数项都设置为零。这只是一个例子,真正的问题是一般的稀疏数组 这个答案对我帮助很大,尽管在读取数据时,数据大小是恒定的: 我怀疑我可以通过计算d_src中0的数量来解决这个问题,然后只分配d_res为

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

我希望实现的是流压缩操作,其中只保留非零元素。根据下面的示例代码,我已经基本上实现了这一点。我不确定如何处理的部分是,在压实发生后,处理所有以d_res和h_res表示的额外填充空间

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

这个答案对我帮助很大,尽管在读取数据时,数据大小是恒定的:

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

我感觉到,通过巧妙地使用迭代器或其他一些推力特性,可以很容易地解决这个问题

#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;
}
#包括
#包括
#包括
//谓词函子
结构不是零
{
__主机设备__
布尔运算符()(常量int x)
{
返回(x!=0);
}
};
使用名称空间std;
内部主(空)
{
尺寸N=100;
//宿主载体
推力:主向量h\u src(N);
//例如,用一些零和一些非零数据填充
对于(int i=0;icout您似乎忽略了
copy\u 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);
//复制到设备
推力::装置矢量d_src=h_src;
//结果向量
推力:设备向量d_res(d_src.size());
//将非零元素从d_src复制到d_res
如果(d_src.begin(),d_src.end(),d_res.begin(),不是零()),则自动生成结果;
//复制回主机
推力::主机向量h_res(d_res.begin(),result_end);

这样做的大小
h_res
只保留非零,并且只从流压缩的输出中复制非零。不需要额外的计算。

这正是我想要的,谢谢。看起来'remove'有类似的返回,所以现在我还可以比较这种方法的移除时间,然后排序到e反转,排序,然后删除。