1

当我们有一个程序需要对大型数据集进行大量操作并且对每个数据元素的操作是独立的时,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)。然后 function2 和 function3 分别对这些 X、Y 数据上的每个元素分别应用操作。

由于所有函数的操作都独立应用于数据集的每个元素,因此使用 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 来加速这样的程序的最佳实践是什么?

4

1 回答 1

0

我不认为您将问题拆分为内核的方式存在普遍问题,尽管很难说,因为您没有非常具体。您希望您的 while 循环多久运行一次?

如果您的内核所做的工作可以忽略不计,但外部循环正在进行大量迭代,您可能希望将内核合并为一个,并在内核本身内进行一些迭代,如果这对您的问题有效。

否则:

如果您的性能出乎意料地差,您很可能需要查看每个内核的效率,以及它们的数据访问模式。除非相邻的工作项正在读取/写入相邻的数据(理想情况下:16 个工作项一次从 64 字节缓存行中读取 4 个字节),否则您可能会浪费内存带宽。如果您的内核包含大量条件或非常量循环迭代,那将花费您等。

你没有指定你得到什么样的运行时,什么样的工作规模,(几十?几千?几百万的算术运算?你的数据集有多大?)或什么硬件。(计算卡?笔记本电脑 IGPU?)“显着开销”可能意味着很多不同的东西。5毫秒?1秒?

Intel、nVidia 和 AMD 都发布了优化指南——你读过这些吗?

于 2016-07-21T07:20:45.573 回答