在 OpenCL 中通过 __local 内存传递参数
Passing arguments through __local memory in OpenCL
我对 OpenCL 中的 __local 内存感到困惑。
我读了一些规范说数据流必须从主机到
__Global,然后是 __Local。
但我也看到了一些像这样的内核函数:
__kernel void foo(__local float * a)
我想知道数据是如何直接传输到 __local
这样记忆?
谢谢。
无法在主机端填充本地缓冲区。所以你必须关注流量主机 -> __global -> __local.
本地缓冲区可以在主机端创建,然后作为内核参数传递,也可以在内核中的 gpu 端创建。
在主机端创建本地缓冲区有利于在内核 运行 之前决定其大小,如果每次内核 运行.[= 时本地缓冲区大小都需要不同,这可能很重要。 10=]
除了单个工作组外,本地内存对任何事物都不可见,并且可以在许多体系结构上由硬件分派工作组时进行分配。可以在每个 CU 上混合来自不同内核的多个工作组的硬件将允许调度组件为每个发出的组分块本地内存。组启动前不存在,组终止后不存在。正如其他答案所指出的那样,该区域的大小就是您传入的内容。
这样做的结果是,在许多体系结构上,从主机填充本地内存的唯一方法是由编译器插入内核代码,从全局内存中复制数据。鉴于此作为基础,程序员手动执行它在性能方面并没有更差,并且可以更好地控制所发生的事情。您不会最终遇到编译器总是生成复制代码并最终复制超过真正必要的情况,因为 API 没有明确说明哪些内存被复制,哪些不是。
总而言之,您无法以任何自动方式填充本地内存。在实践中,你很少会想要这样做,因为手动操作让你有机会只将第一阶段的结果放入本地,删除额外的复制操作,或者在进入本地的途中将数据转换为本地,允许填充或数据转置消除银行冲突等。
正如@doqtor 所说,内核参数上的本地内存大小可以通过 clSetKernelArg
调用指定。
幸运的是,OpenCL 1.2+支持VLA(可变长度数组),不再需要本地内存内核参数。
我对 OpenCL 中的 __local 内存感到困惑。 我读了一些规范说数据流必须从主机到 __Global,然后是 __Local。 但我也看到了一些像这样的内核函数:
__kernel void foo(__local float * a)
我想知道数据是如何直接传输到 __local 这样记忆?
谢谢。
无法在主机端填充本地缓冲区。所以你必须关注流量主机 -> __global -> __local.
本地缓冲区可以在主机端创建,然后作为内核参数传递,也可以在内核中的 gpu 端创建。 在主机端创建本地缓冲区有利于在内核 运行 之前决定其大小,如果每次内核 运行.[= 时本地缓冲区大小都需要不同,这可能很重要。 10=]
除了单个工作组外,本地内存对任何事物都不可见,并且可以在许多体系结构上由硬件分派工作组时进行分配。可以在每个 CU 上混合来自不同内核的多个工作组的硬件将允许调度组件为每个发出的组分块本地内存。组启动前不存在,组终止后不存在。正如其他答案所指出的那样,该区域的大小就是您传入的内容。
这样做的结果是,在许多体系结构上,从主机填充本地内存的唯一方法是由编译器插入内核代码,从全局内存中复制数据。鉴于此作为基础,程序员手动执行它在性能方面并没有更差,并且可以更好地控制所发生的事情。您不会最终遇到编译器总是生成复制代码并最终复制超过真正必要的情况,因为 API 没有明确说明哪些内存被复制,哪些不是。
总而言之,您无法以任何自动方式填充本地内存。在实践中,你很少会想要这样做,因为手动操作让你有机会只将第一阶段的结果放入本地,删除额外的复制操作,或者在进入本地的途中将数据转换为本地,允许填充或数据转置消除银行冲突等。
正如@doqtor 所说,内核参数上的本地内存大小可以通过 clSetKernelArg
调用指定。
幸运的是,OpenCL 1.2+支持VLA(可变长度数组),不再需要本地内存内核参数。