c ++将vector放到struct而不复制

时间:2016-08-01 11:03:28

标签: c++ vector visual-studio-2008 struct cuda

如何在c ++中将vector放到struct(msvc 2008)。

例如......

我有头文件.hh:

template <typename dtype> struct c_Cudamat_Struct1 {
    thrust::device_vector<dtype> deviceVector;
    dtype * dataHost;
    dtype * dataDevice;
    int onDevice;
    int onHost;
    (void *) shape;
    int size;
    int isTrans; // 0 or 1
    int ownsData;
    int itemsize;

};

template <typename dtype> int thrust_copy_to_device(c_Cudamat_Struct1<dtype> * mat);
template int thrust_copy_to_device<double>(c_Cudamat_Struct1<double> * mat);
template int thrust_copy_to_device<float>(c_Cudamat_Struct1<float> * mat);
template int thrust_copy_to_device<long>(c_Cudamat_Struct1<long> * mat);
template int thrust_copy_to_device<int>(c_Cudamat_Struct1<int> * mat);
template int thrust_copy_to_device<char>(c_Cudamat_Struct1<char> * mat);

我有一些主要的(?)。cu文件:

template <typename dtype> int thrust_copy_to_device(c_Cudamat_Struct1<dtype> * mat){

    print_memory_gpu("1. Start:::");

    thrust::device_vector<dtype> deviceVector(mat->dataHost, mat->dataHost + mat->size);

    print_memory_gpu("2. Create deviceVector:::");

    mat->deviceVector = deviceVector;

    print_memory_gpu("3. Put deviceVector to mat:::");


    mat->deviceVector=thrust_vector_fill_range<dtype>(mat->deviceVector, 1, mat->size);

    print_memory_gpu("4. mat->deviceVector linspace:::");


    return 0;
}

但它制作副本:

  
      
  1. Start ::: Free / Total GPU memory(MB):1541 / -2048
  2.   
  3. 创建deviceVector ::: Free /总GPU内存(MB):1160 / -2048
  4.   
  5. 将deviceVector放到mat ::: Free /总GPU内存(MB):778 / -2048
  6.   
  7. mat-&gt; deviceVector linspace ::: Free / Total GPU memory(MB):876 / -2048
  8.   

EDIT 000/999

突出显示重要内容(其他我将使用&#34; mat->dataDevice&#34;)的指针来处理......

template <typename dtype> int thrust_copy_to_device(c_Cudamat_Struct1<dtype> * mat){

    print_memory_gpu("1. Start:::");

    thrust::device_vector<dtype> deviceVector(mat->dataHost, mat->dataHost + mat->size);

    print_memory_gpu("2. Create deviceVector:::");

    mat->deviceVector = deviceVector;

    print_memory_gpu("3. Put deviceVector to mat:::");


    return 0;
}

我怎么能改变这一部分:

thrust::device_vector<dtype> deviceVector(mat->dataHost, mat->dataHost + mat->size);

print_memory_gpu("2. Create deviceVector:::");

mat->deviceVector = deviceVector;

类似于:

thrust::device_vector<dtype> mat->deviceVector(mat->dataHost, mat->dataHost + mat->size);

print_memory_gpu("2. Create deviceVector:::");

EDIT 001/999

问题是指针没问题,但我仍然需要这个向量并使它可以从struct。

获得

我应该使用一些狡猾的方法来代替这个结构创建类吗?

编辑002/999

最简单的解决方案似乎是创建类而不是struct:

在标题.hh文件中:

template <class dtype> class C_Cudamat_Struct{
    private:
        thrust::device_vector<dtype> deviceVector;
    public:
        C_Cudamat_Struct();
        dtype * dataHost;
        dtype * dataDevice;
        int onDevice;
        int onHost;
        (void *) shape;
        int size;
        int isTrans; // 0 or 1
        int ownsData;
        int itemsize;

        int set_device_vector();

};

template class C_Cudamat_Struct<double>;
template class C_Cudamat_Struct<float>;
template class C_Cudamat_Struct<long>;
template class C_Cudamat_Struct<int>;

在main(?)。cu文件中:

template <class dtype> int C_Cudamat_Struct<dtype>::set_device_vector(){
    print_memory_gpu("1. Start:::");

    thrust::device_vector<dtype> deviceVector(dataHost, dataHost + size);

    print_memory_gpu("2. Create deviceVector:::");

    //mat->deviceVector = std::move (deviceVector);

    print_memory_gpu("3. Put deviceVector to mat:::");

    deviceVector=thrust_vector_fill_range<dtype>(deviceVector, 1, size);

    print_memory_gpu("4. mat->deviceVector linspace:::");

    return 0;

}

template <class dtype> C_Cudamat_Struct<dtype>::C_Cudamat_Struct(){

}

1 个答案:

答案 0 :(得分:1)

简短的回答是:C ++编译器不会为你做,你必须自己做。如果您不想复制,请在结构中将std::shared_ptrstd::unique_ptr存储到矢量中。

或者,首先构造struct,使用reserve()保留struct向量中预期的元素数,然后直接填充struct的向量。您不能先将矢量构造为单独的对象,然后将其复制到某个地方,而不是实际制作副本。

看起来你发现了这个载体的多个副本:

 mat->deviceVector=thrust_vector_fill_range<dtype>(mat->deviceVector, 1, mat->size);

我怀疑thrust_vector_fill_range()不通过引用获取其参数,而是通过值。因此,这将为函数参数制作整个向量的副本。然后,返回的矢量将再次被复制。没错,返回的向量会在之后立即被销毁,但是你的编译器太旧了,无法支持移动语义,所以这必须以老式的方式完成。

总而言之,如果您不想制作不必要的矢量副本,请正确编写代码,但不能执行此操作。不要实例化向量的单独副本,只是将其复制到结构中。 resize()reserve()并填充结构的向量,然后始终通过引用传递它。