Opencl 链式交换运算是否提高了性能?

Opencl 链式交换运算是否提高了性能?,opencl,pyopencl,Opencl,Pyopencl,我有一些与pyopencl库中的python接口的OpenCL内核。内核用于加速交换操作(如加法或乘法),其中操作输入变量的顺序无关紧要。进行添加的内核可能如下所示: \uuuuu内核无效添加(\uuuu全局常量浮点*a\u g, __全局常量浮点*b_g, __全局浮点*res_g) { int gid=获取全局id(0); res_g[gid]=a_g[gid]+b_g[gid]; } 为简单起见,假设所有的操作缓冲区(a_g,b_g,res_g)都具有相同的大小和一维。全局工作大小设置为

我有一些与pyopencl库中的python接口的OpenCL内核。内核用于加速交换操作(如加法或乘法),其中操作输入变量的顺序无关紧要。进行添加的内核可能如下所示:

\uuuuu内核无效添加(\uuuu全局常量浮点*a\u g,
__全局常量浮点*b_g,
__全局浮点*res_g)
{
int gid=获取全局id(0);
res_g[gid]=a_g[gid]+b_g[gid];
}
为简单起见,假设所有的操作缓冲区(
a_g
b_g
res_g
)都具有相同的大小和一维。全局工作大小设置为启动内核之前缓冲区的大小,结果存储在
res\u g
缓冲区中

这些操作以顺序方式工作,一个内核的输出被用作下一个内核的输入。考虑到所有这些内核看起来都像上面的代码片段,我可以通过编写以下内核简单地将4个输入“链接”在一起:

\uuuuu内核无效添加\uu链接(\uuu全局常量浮点*a\u g,
__全局常量浮点*b_g,
__全局常量浮点*c_g,
__全局常量浮点*d_g,
__全局浮点*res_g)
{
int gid=获取全局id(0);
res_g[gid]=a_g[gid]+b_g[gid]+c_g[gid]+d_g[gid];
}
这样,就不需要分配中间结果缓冲区,而且在启动新线程时也没有开销

这是常见的优化吗?这样做的利弊是什么


在OpenCL中有没有规范的方法来链接内核?编译时可能不知道需要链接的操作的数量。

通过将多个内核的操作组合到一个内核中来减少内核调用意味着更少的内存分配和来自全局内存的内存传输,从而显著减少执行时间

如果在整个程序中添加的数量是恒定的,那么可以利用OpenCL在运行时从字符串编译的优势。这意味着:您可以在运行时修改包含OpenCL代码的字符串,然后编译并运行它。通过这种方式,您可以通过字符串连接添加数量可变的内核参数和求和项


然而,如果求和项的数量在程序的一次执行中要花费很多次,并且是不可预测的,那么双参数内核就是最好的选择。否则,您将不得不多次重新编译OpenCL代码,这将带来巨大的开销。

通过将多个内核的操作组合到一个内核中来减少内核调用,意味着更少的内存分配和来自全局内存的内存传输,这将显著减少执行时间

如果在整个程序中添加的数量是恒定的,那么可以利用OpenCL在运行时从字符串编译的优势。这意味着:您可以在运行时修改包含OpenCL代码的字符串,然后编译并运行它。通过这种方式,您可以通过字符串连接添加数量可变的内核参数和求和项


然而,如果求和项的数量在程序的一次执行中要花费很多次,并且是不可预测的,那么双参数内核就是最好的选择。否则,您将不得不多次重新编译OpenCL代码,这将带来巨大的开销。

作为旁注:我不确定链接是否是正确的术语作为旁注:我不确定链接是否是正确的术语像这样操作字符串感觉有点不正常,但我想这正是我想做的。像这样操纵字符串感觉有点不舒服,但我想这正是我想做的。