当我们有一个程序需要对大型数据集进行大量操作并且每个数据元素上的操作是独立的时,OpenCL可以是使其更快的好选择之一。我有一个类似以下的程序:
while( function(b,c)!=TRUE)
{
[X,Y] = function1(BigData);
M = functionA(X);
b = function2(M);
N = functionB(Y);
c = function3(N);
}
这里,function1应用于BigData上的每个元素,并生成另外两个大数据集(X,Y)。然后,分别对这些X,Y数据上的每个元素分别应用function2和function3。
由于所有函数的操作都独立地应用于数据集的每个元素,因此使用GPU可能会使其更快。所以我想出了以下内容:
while( function(b,c)!=TRUE)
{
//[X,Y] = function1(BigData);
1. load kernel1 and BigData on the GPU. each of the thread will work on one of the data
element and save the result on X and Y on GPU.
//M = functionA(X);
2a. load kernel2 on GPU. Each of the threads will work on one of the
data elements of X and save the result on M on GPU.
(workItems=n1, workgroup size=y1)
//b = function2(M);
2b. load kernel2 (Same kernel) on GPU. Each of the threads will work on
one of the data elements of M and save the result on B on GPU
(workItems=n2, workgroup size=y2)
3. read the data B on host variable b
//N = functionB(Y);
4a. load kernel3 on GPU. Each of the threads will work on one of the
data element of Y and save the result on N on GPU.
(workItems=n1, workgroup size=y1)
//c = function2(M);
4b. load kernel3 (Same kernel) on GPU. Each of the threads will work
on one of the data element of M and save the result on C on GPU
(workItems=n2, workgroup size=y2)
5. read the data C on host variable c
}
然而,这段代码涉及的开销对我来说似乎很重要(我已经实现了一个测试程序并在GPU上运行)。如果内核有某种同步,它可能会以更慢的速度结束。
我也相信工作流程很常见。那么使用OpenCL加速这样的程序的最佳做法是什么。
答案 0 :(得分:0)
我不认为你将问题分解为内核的方式存在一般性问题,尽管很难说你还没有进入内核具体。你经常期望你的while循环运行吗?
如果您的内核做的工作可以忽略不计,但外部循环正在进行大量的迭代,您可能希望将内核合并为一个,并在内核中进行一些迭代,如果这对您的问题有效。
否则:
如果您的性能出乎意料地糟糕,那么您很可能需要关注每个内核的效率,以及可能的数据访问模式。除非相邻工作项正在读/写相邻数据(理想情况下:16个工作项一次从64字节高速缓存行读取4个字节),否则可能会浪费内存带宽。如果你的内核包含许多条件或非常量循环迭代,那么这将花费你等等。
您没有具体说明您的工作时间类型,工作规模,(数十万?数百万算术运算?您的数据集有多大?)或硬件。 (计算卡?笔记本电脑IGPU?)"显着的开销"可能意味着很多不同的事情。 5ms的? 1秒钟?
英特尔,nVidia和AMD都发布了优化指南 - 你读过这些吗?