我是OpenCL新手,在处理内存和本地工作组时遇到了一些困难。
我有一个四维数据结构,即float30100。目前,我在每个法线上迭代前两个维度,并将得到的2025x100矩阵传递给下面的CPU函数。
// 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函数,但是我需要实现三个不同的规范化函数,我不知道它们中是否有一个与内置函数匹配。无论如何,我试着测试它,但是我收到了一个错误,它没有找到任何匹配的内建函数来规范它(浮点*向量)。
发布于 2016-02-02 20:46:59
您可以轻松地并行化GPU上的完整功能,而不仅仅是标记为“多线程”的部分。在OpenCL中,线程/工作项被划分为本地工作组。在同一个工作组中,线程可以一起工作,使用本地共享内存共享数据,并使用屏障进行同步。您可以在每个工作组中处理一个列。每个列都是完全独立的,因此不需要工作组之间的同步。
在每个工作组中,我们可以使用每个线程来处理向量的4或8个元素。(如果您只处理每个工作项的元素,您的工作组将大于最大工作组大小)这里的棘手部分是如何并行计算向量的最大值、最小值和和:这里我们可以使用一个名为“并行约简”的并行编程原语。下面是带有精彩幻灯片的视频,说明了该技术:s
您可以将此技术用于向量、最小和最大值之和,以并行计算最小值、最大值和平均值。如果同时完成这三项任务,它甚至会比三次单独的减少稍微快一点,因为您需要更少地同步。您还可以使用局部变量来存储向量的临时结果,并且在开始时只在vectori中读取一次,在向量上的所有计算都完成后,在最后写回vectori。可以节省很多内存带宽。
https://stackoverflow.com/questions/35120889
复制相似问题