带有嵌入对象/结构的 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 运算符和排序)

是否可以将带有许多包的 Python 脚本嵌入到 C# 中?

ps置入嵌入对象为啥有白色背景色