带有嵌入对象/结构的 cudaMalloc/cudaMemcpy
Posted
技术标签:
【中文标题】带有嵌入对象/结构的 cudaMalloc/cudaMemcpy【英文标题】:cudaMalloc/cudaMemcpy with embedded objects/structures 【发布时间】:2018-05-10 15:01:35 【问题描述】:我正在开发一个相当大的并行应用程序,使用 OpenMPI 在 MPI 进程之间分配数据。将 MPI 与一些序列化库一起使用,例如“cereal”,可以非常轻松地传递大量嵌入的对象。为了暗示我所说的多嵌入结构是什么意思,我目前正在使用简化版本,例如:
// structures for CUDA - this is inside std::vector<struct_multi_data> multi_data_vector
struct struct_multi_data
int intended_kernel_block;
int intended_kernel_thread;
std::vector<float> data_float;
std::vector<float> data_int;
float result;
;
struct struct_unique_data
// this structure is shared among all blocks/threads
float x;
float y;
float z;
;
class Data_object
// functions
public:
Data_object();
~Data_object();
int resize(int multi_data_vector_len, int data_float_len, int data_int_len);
void set_id(int id);
int clean(void);
int get_multi_data_len();
int get_multi_data(struct_multi_data * data, int vector_element);
int set_multi_data(struct_multi_data * data, int vector_element);
// variables
private:
std::vector<struct_multi_data> multi_data_vector;
struct_unique_data unique_data;
int data_id;
;
* 上面的代码被简化了,我去掉了序列化函数和其他一些基本的东西,但整体结构保持不变
简单来说,我在Data_object周围移动,包含vectorstruct_multi_data,这是一个结构向量,其中每个结构struct_multi_data 包含一些 vectorfloat。
我有充分的理由将所有数据嵌入到 1 个 Data_object 中,因为它简化了 MPI 发送和接收。
问题
是否有一些使用 cudaMalloc/cudaMemcpy 函数将 Data_object 移动到 GPU 内存的舒适方法?
常规 std::vector 似乎有问题。我不想依赖 Thrust 库,因为我不确定它是否适用于我的 MPI 序列化解决方案。
编辑问题 我可以将 managed 用于我的 Data_object,还是使用 cudaMallocManaged() 使 GPU 可以访问数据?
请阅读
Data_object 的大小在程序执行开始时就已经很好地定义了。没有向量在其他任何地方改变大小,但在执行的开始。那么我为什么要使用向量呢?这样我可以通过传递参数来设置向量的大小,而不是重新编译程序来改变数据大小(比如当数据被定义为数组时)。
对评论的回应 1)我认为可以用指向数组的指针替换所有向量。
【问题讨论】:
一言以蔽之,否。 这在使用 std::vector 时变得有些困难,我想你可能误解了它们是如何分配内存的。在这种情况下,仅使用动态分配的数组(向量也是如此!)会更容易,因为至少您知道需要复制哪个内存块。你可以用与向量完全相同的方式初始化它们的大小。 还是不行。托管内存无法解决无法在 GPU 上使用主机容器类的问题,并且没有 CUDA API 支持任何形式的“深度复制” 【参考方案1】:不,这个问题中的额外部分没有帮助。 std::vector
只是不打算那样工作:它“拥有”它指向的内存,如果你将它复制到其他地方(甚至在主机内存中)并从那里使用它,你只会破坏你的记忆.此外,std::vector
代码甚至无法在 GPU 上运行,因为它不是 __device__
-code。
你可以做的是使用std::span
,它不拥有内存,而不是std::vector
。如果你这样做了,并且内存是被管理的,那么 mem-copying 一个类可能会起作用。
请注意,我完全忽略了向量以外的成员,因为这似乎是这里的主要问题。
【讨论】:
以上是关于带有嵌入对象/结构的 cudaMalloc/cudaMemcpy的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有嵌入对象的对象返回给 jquery get 调用?
使用 mongoid 在 rails 中保存带有嵌入对象/文档的对象
查询 Mongoid/rails 3 中的嵌入对象(“低于”、Min 运算符和排序)