首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确设计opencl中的向量归一化(工作组大小和内核)

如何正确设计opencl中的向量归一化(工作组大小和内核)
EN

Stack Overflow用户
提问于 2016-01-31 23:37:09
回答 1查看 778关注 0票数 0

我是OpenCL新手,在处理内存和本地工作组时遇到了一些困难。

我有一个四维数据结构,即float30100。目前,我在每个法线上迭代前两个维度,并将得到的2025x100矩阵传递给下面的CPU函数。

代码语言:javascript
复制
// num_columns = 100; num_rows = 2025
for (int column = 0; column < num_cols; column++){
    vector = matrix[column];

    float min = vector[0];
    float max = vector[0];
    for (int i = 0; i < num_rows; i++){
        if(vector[i] < min){min = vector[i];}
        if(vector[i] > max){max = vector[i];}
    }
    float diff = max-min + epsilon;

    for(int i = 0; i < num_rows; i++){
        vector[i] = (vector[i]-min)/diff; //MULTI-THREAD HERE
    }

    float mean = 0;
    for (int i = 0; i < num_rows; i++){
        mean += vector[i];
    }
    mean = mean/num_rows;

    for (int i = 0; i < num_rows; i++){
        vector[i] = vector[i]-mean + epsilon; //MULTI-THREAD HERE
    }

    float norm = 0;
    for (int i = 0; i < num_rows; i++){
        norm += vector[i]*vector[i];
    }
    norm = (float) sqrt(norm);

    if (norm > 0){
        for (int i = 0; i < num_rows; i++){
            vector[i] = vector[i]/norm; //MULTI-THREAD HERE
        }
    }
}

我已经评论了我认为我从使用OpenCL中获益的地方。迭代每一列、编写向量(设备缓冲区)、执行规范化操作、然后将其读回主机,都是很昂贵的。GPU ( htc m8上的Adreno 330 )拥有内存,可以同时缓冲整个2025x100矩阵。但是,我必须将它压平到一个一维浮点数组中,而且我不知道如何一次只在缓冲区的一部分(一个向量)上执行内核。

我已经读了很多关于GPU体系结构的文章,但是我似乎无法理解设计这个问题的正确方法,以及是否应该利用本地工作组来解决这个问题。我希望我已经提供了足够的信息来引导我朝着正确的方向前进。

编辑:我知道有一个内置的CLnormalize函数,但是我需要实现三个不同的规范化函数,我不知道它们中是否有一个与内置函数匹配。无论如何,我试着测试它,但是我收到了一个错误,它没有找到任何匹配的内建函数来规范它(浮点*向量)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-02 20:46:59

您可以轻松地并行化GPU上的完整功能,而不仅仅是标记为“多线程”的部分。在OpenCL中,线程/工作项被划分为本地工作组。在同一个工作组中,线程可以一起工作,使用本地共享内存共享数据,并使用屏障进行同步。您可以在每个工作组中处理一个列。每个列都是完全独立的,因此不需要工作组之间的同步。

在每个工作组中,我们可以使用每个线程来处理向量的4或8个元素。(如果您只处理每个工作项的元素,您的工作组将大于最大工作组大小)这里的棘手部分是如何并行计算向量的最大值、最小值和和:这里我们可以使用一个名为“并行约简”的并行编程原语。下面是带有精彩幻灯片的视频,说明了该技术:s

您可以将此技术用于向量、最小和最大值之和,以并行计算最小值、最大值和平均值。如果同时完成这三项任务,它甚至会比三次单独的减少稍微快一点,因为您需要更少地同步。您还可以使用局部变量来存储向量的临时结果,并且在开始时只在vectori中读取一次,在向量上的所有计算都完成后,在最后写回vectori。可以节省很多内存带宽。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35120889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档