考虑以下问题:
您拥有一个只有一个GPU和一个CPU的计算环境。在GPU上,您运行一个程序,对1e6浮点数数组进行计算。这个计算步骤重复n次(进程1)。每次计算步骤完成后,我将数组从设备内存传输到主机内存。传输完成后,使用串行算法在CPU上分析数据(进程2)。
该程序以串行方式工作。我想知道如何并行化进程1和进程2,以减少总程序运行时间。必须让进程1等待进程2完成,反之亦然。
我知道CUDA内核是异步调用的,也知道有带固定主机内存的异步复制操作。但是,在这种情况下,我需要等待GPU完成后,CPU才能开始处理输出。如何传递这些信息?
我尝试修改了多线程CPU生产者/消费者代码,但没有成功。最终,我将管理GPU和CPU工作负载的两个CPU线程串行化了。然而,在这里,我的GPU需要等待CPU完成才能继续进行......
我希望通过 cudastreams 来实现同步。但我认为它们只适用于设备函数调用。我需要使用 MPI 吗,还是有其他选项来在异构计算平台上同步进程?我读到 OpenCL 支持此操作,因为所有计算设备都组织在一个“上下文”中。是否不可能使用 CUDA 实现相同的操作?
假如我的序列化 CPU 操作比 GPU 操作长 4 倍,我打算创建 4 个 CPU 消费者。
非常感谢您的任何见解!
编辑:CPU 函数包含无法并行化的串行代码。
您拥有一个只有一个GPU和一个CPU的计算环境。在GPU上,您运行一个程序,对1e6浮点数数组进行计算。这个计算步骤重复n次(进程1)。每次计算步骤完成后,我将数组从设备内存传输到主机内存。传输完成后,使用串行算法在CPU上分析数据(进程2)。
该程序以串行方式工作。我想知道如何并行化进程1和进程2,以减少总程序运行时间。必须让进程1等待进程2完成,反之亦然。
我知道CUDA内核是异步调用的,也知道有带固定主机内存的异步复制操作。但是,在这种情况下,我需要等待GPU完成后,CPU才能开始处理输出。如何传递这些信息?
我尝试修改了多线程CPU生产者/消费者代码,但没有成功。最终,我将管理GPU和CPU工作负载的两个CPU线程串行化了。然而,在这里,我的GPU需要等待CPU完成才能继续进行......
#include <mutex>
#include <condition_variable>
#include "ProducerConsumerBuffer.hpp"
ProducerConsumerBuffer::ProducerConsumerBuffer(int capacity_in, int n): capacity(capacity_in), count(0) {
c_bridge = new float[n];
c_CPU = new float[n];
}
ProducerConsumerBuffer::~ProducerConsumerBuffer(){
delete[] c_bridge;
delete[] c_CPU;
}
void ProducerConsumerBuffer::upload(device_pointers *d, params &p, streams *s){
std::unique_lock<std::mutex> l(lock);
not_full.wait(l, [this](){return count != 1; });
copy_GPU_to_CPU(d,c_bridge,p,s);
count++;
not_empty.notify_one();
}
void ProducerConsumerBuffer::fetch(){
std::unique_lock<std::mutex> l(lock);
not_empty.wait(l, [this](){return count != 0; });
std::swap(c_bridge,c_CPU);
count--;
not_full.notify_one();
}
我希望通过 cudastreams 来实现同步。但我认为它们只适用于设备函数调用。我需要使用 MPI 吗,还是有其他选项来在异构计算平台上同步进程?我读到 OpenCL 支持此操作,因为所有计算设备都组织在一个“上下文”中。是否不可能使用 CUDA 实现相同的操作?
假如我的序列化 CPU 操作比 GPU 操作长 4 倍,我打算创建 4 个 CPU 消费者。
非常感谢您的任何见解!
编辑:CPU 函数包含无法并行化的串行代码。