【发布时间】: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周围移动,包含vector{struct_multi_data},这是一个结构向量,其中每个结构struct_multi_data 包含一些 vector{float}。
我有充分的理由将所有数据嵌入到 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 支持任何形式的“深度复制”
标签: c++ vector struct cuda mpi