考虑以下问题:
您有一个具有单个gpu和一个cpu的计算环境。在gpu上,运行一个在1e6浮点数数组上执行计算的程序。此计算步骤重复n次(过程1)。在每个计算步骤之后,我将数组从设备内存传输到主机内存。一旦传输完成,数据就会被分析,调用CPU上的串行算法(process 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();
}我希望能有办法用棍棒做这件事。但我认为它们只适用于设备功能调用。我是否需要使用MPI代替,还是有另一种选择来同步异构计算平台上的进程?我读过关于OpenCL支持这个操作的文章,因为所有的计算设备都是在一个“上下文”中组织的。对数据自动化系统不可能做同样的事情吗?
如果我的序列化CPU操作运行的时间是GPU操作的4倍,我计划创建4个CPU使用者。
任何洞察力都将不胜感激!
编辑: CPU功能包含串行代码,这是不可并行的。
发布于 2015-04-27 22:23:00
如果不使用多个线程或进程,或者严重地使CPU算法复杂化,以实现可容忍的调度延迟,就无法做您想做的事情。这是因为您必须能够以正确的频率以低延迟的方式命令GPU来处理GPU工作负载的数据,但是CPU工作负载听起来并不是微不足道的,并且必须考虑到循环的运行时。
因此,为了确保CPU和GPU都在连续处理并实现最高吞吐量和最低延迟,您必须将GPU命令部分和昂贵的CPU计算部分分解为不同的线程--在2之间是某种IPC --最好是共享内存。如果使用与CUDA类似的专用CPU处理线程,并使用它的cudaEvent_t跨线程,并使GPU命令线程也命令CPU线程-即一个命令线程和两个处理从线程(GPU,CPU),您可能可以简化一些任务。
https://stackoverflow.com/questions/29850816
复制相似问题