Sha*_*izi 7 c c++ labview cuda
我正准备将我写入CUDA的程序转换为希望提高处理速度.
现在显然我的旧程序一个接一个地执行许多函数,我已经在主程序中分离了这些函数并按顺序调用每个函数.
void main ()
{
*initialization of variables*
function1()
function2()
function3()
print result;
}
Run Code Online (Sandbox Code Playgroud)
这些函数本质上是串行的,因为funtion2取决于funtion1的结果.
好的,现在我想将这些函数转换为内核,并在函数中并行运行任务.
是否像以并行方式重写每个函数一样简单,然后在我的主程序中,一个接一个地调用每个内核?这比它需要的慢吗?例如,我可以让我的GPU直接执行下一个并行操作而无需返回CPU来初始化下一个内核吗?
显然,我会将所有运行时变量保留在GPU内存上以限制正在进行的数据传输量,所以我是否应该担心内核调用之间的时间?
我希望这个问题很清楚,如果不是,请让我详细说明.谢谢.
这是一个额外的问题,以便我可以检查我的理智.最终这个程序的输入是一个视频文件,通过不同的功能,每一帧都会产生一个结果.我的计划是一次抓取多个帧(比如8个独特的帧),然后除以这8个帧中我拥有的块总数,然后块中的多个线程将对图像数据进行更多的并行操作,例如矢量加法,傅里叶变换等.
这是解决问题的正确方法吗?
在某些情况下,您可以在GPU上以完全潜在的速度运行程序,而只需很少的移植工作来处理普通的CPU版本,这可能就是其中之一.
如果你有可能有这样的功能:
void process_single_video_frame(void* part_of_frame)
{
// initialize variables
...
intermediate_result_1 = function1(part_of_frame);
intermediate_result_2 = function2(intermediate_result_1);
intermediate_result_3 = function3(intermediate_result_2);
store_results(intermediate_result_3);
}
Run Code Online (Sandbox Code Playgroud)
并且您可以同时处理许多part_of_frames.说,几千,
并且 function1()
,function2()
并且function3()
经历几乎相同的代码路径(也就是说,程序流程并不严重依赖于框架的内容),
那么,本地记忆可能会为你做所有的工作.本地内存是一种存储在全局内存中的内存.它以一种微妙而深刻的方式与全局内存不同......内存只是以相邻线程将访问相邻的32位字的方式进行交错,如果线程全部从线程读取,则使内存访问完全合并.其本地内存阵列的相同位置.
您的程序流程将是您通过复制part_of_frame
到本地数组并准备其他本地数组以获得中间结果.然后,将指针传递给代码中各种函数之间的本地数组.
一些伪代码:
const int size_of_one_frame_part = 1000;
__global__ void my_kernel(int* all_parts_of_frames) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
int my_local_array[size_of_one_frame_part];
memcpy(my_local_array, all_parts_of_frames + i * size_of_one_frame_part);
int local_intermediate_1[100];
function1(local_intermediate_1, my_local_array);
...
}
__device__ void function1(int* dst, int* src) {
...
}
Run Code Online (Sandbox Code Playgroud)
总之,这种方法可以让您使用CPU功能几乎不变,因为并行性不是来自创建函数的并行版本,而是通过并行运行整个函数链.并且通过在本地阵列中交错存储器的硬件支持使这成为可能.
笔记:
part_of_frame
从全局到本地内存的初始副本未合并,但希望您有足够的计算来隐藏它.
在计算能力<= 1.3的设备上,每个线程只有16KiB的本地内存可用,这对于您part_of_frame
和其他中间数据可能不够.但是在计算能力> = 2.0时,这已经扩展到512KiB,这应该是充足的.
回答你的一些问题:
调用内核并不昂贵,所以不要害怕从GPU返回到CPU的程序流.只要您将结果保存在GPU内存中,就不会有太多开销.如果您愿意,可以创建一个简单地调用序列中其他设备函数的内核.AFAIK这将更难调试和配置文件,我不确定是否可以配置内核调用的函数.
关于并行化:
我认为任何允许你在多个数据流上运行计算的想法都是好的.您的代码越像着色器越好(意味着它将具有在gpu上快速运行所需的特性).多帧的想法很好.关于它的一些提示:尽可能减少同步,尽可能少地访问内存,尝试增加计算时间与IO请求时间的比率,使用gpu寄存器/共享内存,更喜欢多次读取一对一写入设计.
归档时间: |
|
查看次数: |
2065 次 |
最近记录: |