OpenCL 内核和传统循环

问题描述 投票:0回答:1

我正在研究OpenCL,我不明白C/C++代码中的传统循环与内核代码之间的关系。 只是为了弄清楚这样的情况:

所以我的问题是:在传统循环中,我有

n
变量作为边界,而在内核代码中我没有它,但我有
get_global_id(0)
指示数组的内存范围,这意味着我从0,并迭代直到
get_global_id
与数组的最大大小匹配,在本例中为
n
?还是有什么不同?

因为在另一个例子中我不知道如何编写相应的内核代码

我希望我的问题很清楚,因为我的英语不太好,抱歉。

提前感谢您的帮助,如果有问题请告诉我!

gpu opencl nvidia amd-gpu
1个回答
2
投票

OpenCL 内核的编码类似于 for 循环的单次迭代,但所有迭代都以随机顺序并行运行。

考虑 C++ 中的这个向量加法示例,其中对于

i=0..N-1
,您将向量的每个元素一个接一个地相加:

for(int i=0; i<N; i++) { // loop index i
    C[i] = A[i]+B[i]; // compute one after the other
}

在 OpenCL 中,向量加法看起来像这个 for 循环的内部,但作为一个带有

kernel
关键字和所有向量作为参数的函数:

kernel void add_kernel(const global float* A, const global float* B, global float* C) {
    const int i = get_global_id(0);
    C[i] = A[i]+B[i]; // compute all loop indices i in parallel
}

您可能想知道:

N
在哪里?您将
N
提供给 C++ 端的内核作为其“全局范围”,因此内核知道要并行计算多少元素
i

因为在 OpenCL 内核中,每次迭代都是并行运行的,因此一次迭代与下一次迭代之间不能存在任何数据依赖关系;否则,您必须使用双缓冲区(仅从一个缓冲区读取,仅写入另一个缓冲区)。在第二个使用

A[i] = B[i-1]+B[i]+B[i+1]
的示例中,您正是这样做的:仅从
B
读取,仅写入
A
。具有周期性边界的实现可以无分支完成,请参见here

© www.soinside.com 2019 - 2024. All rights reserved.