相邻工作项上的OpenCL矢量化

相邻工作项上的OpenCL矢量化,opencl,gpu,Opencl,Gpu,假设我有一个OpenCL内核,其中每个工作项执行一个int_32操作,我的GPU支持256位SIMD操作,OpenCL是否能够将8个工作项打包在一起以利用SIMD?i、 e.一个处理单元同时执行多个工作项。如果是,那么什么时候会发生这种情况?在“clBuildProgram”阶段,还是在GPU上实际执行二进制文件时(JIT编译) 第二个似乎更合理,因为这只能在我定义工作组大小后才能决定,例如,如果我说每个工作组1个工作项,那么矢量化就不能发生了 我在“CLuBudid程序”之后查看英伟达PTX文

假设我有一个OpenCL内核,其中每个工作项执行一个int_32操作,我的GPU支持256位SIMD操作,OpenCL是否能够将8个工作项打包在一起以利用SIMD?i、 e.一个处理单元同时执行多个工作项。如果是,那么什么时候会发生这种情况?在“clBuildProgram”阶段,还是在GPU上实际执行二进制文件时(JIT编译)

第二个似乎更合理,因为这只能在我定义工作组大小后才能决定,例如,如果我说每个工作组1个工作项,那么矢量化就不能发生了


我在“CLuBudid程序”之后查看英伟达PTX文件,我仍然看到标量IR,但是我不确定英特尔或AMD。

< P>一般来说,如果GPU将对您的数据执行SIMD指令,它将决定何时编译代码(无论是由在线编译器还是离线编译器)。它可能不会根据您如何/何时定义工作组来决定这一点

至于你的数据是否会矢量化。。。这有点复杂

这取决于您如何准确地布局数据和内核逻辑,以及编译器(可能是在线的)选择优化代码的程度。这在很大程度上也取决于实际的硬件,但我稍后将讨论这一点

  • 向量数据类型(如
    float4
    int4
    float8
    等)是最容易进行向量化的,而且可能甚至不需要优化过程,因为代码非常明确地表示“这些数据都属于一起,并且(可能)是”将对其应用相同的操作,因此,如果您有硬件来执行(但正如我将在下面解释的,这是一个相当大的“如果”)让我们对这些类型使用SIMD指令!”
  • 标量数据类型可能不会得到优化,除非您有一个真正智能的编译器。不是每一个编译器都会得出这样的结论:“好吧,你有
    int
    s称为
    i1
    i2
    i3
    i4
    ,它们都应用了相同的操作,所以让我们对它们进行SIMD!”
  • 工作组中的标量数据类型几乎肯定不会被矢量化。它们仍将并发执行(因为如果不是,那么我们为什么要首先编写GPGPU代码??),但编译器和运行时几乎肯定无法围绕它们进行优化
  • 编辑:如前所述,有多种方法可以使这种矢量化成为可能。但值得注意的是,这些技巧发生在编译时,而不是运行时,这意味着它高度依赖于代码的编写方式,以及使用哪个编译器(以及哪些优化标志,如果存在的话)来编译内核代码
重要的是要记住,所有这些都取决于卡的硬件功能。至少在消费级计算卡(翻译为GPU)中,硬件工程师实际上并没有对其矢量化功能进行重大升级,事实上,他们经常选择减少矢量化,以专注于制造更小的内核,然后将更多的内核堆叠到芯片上。例如,拥有一个128核的卡是一种很好的奢侈,每个卡都可以执行256位SIMD指令,但通常情况下,拥有一个不(或不能)处理SIMD指令的小内核的卡,并简单地堆叠这么多可以并行运行的核(如NVidia最新发布的4k以上),在不依赖程序员编写显式SIMD指令的情况下完成相同的工作(通常更快)


我相信(但不要引用我的话)AMD和NVidia都保证浮点128位矢量化,因为
float4
-类型的对象在图形编程中非常常见,如果您正在进行任何类型的图形处理(这是这类应用程序的标准)它们将从这些对象上的SIMD操作中受益匪浅,但任何不是SIMD操作的对象都可能看不到任何SIMD优化。

一般来说,如果GPU要对数据执行SIMD指令,它将决定何时编译代码(无论是通过在线编译器还是离线编译器)。它可能不会根据您如何/何时定义工作组来决定这一点

至于你的数据是否会矢量化。。。这有点复杂

这取决于您如何准确地布局数据和内核逻辑,以及编译器(可能是在线的)选择优化代码的程度。这在很大程度上也取决于实际的硬件,但我稍后将讨论这一点

  • 向量数据类型(如
    float4
    int4
    float8
    等)是最容易进行向量化的,而且可能甚至不需要优化过程,因为代码非常明确地表示“这些数据都属于一起,并且(可能)是”将对其应用相同的操作,因此,如果您有硬件来执行(但正如我将在下面解释的,这是一个相当大的“如果”)让我们对这些类型使用SIMD指令!”
  • 标量数据类型可能不会得到优化,除非您有一个真正智能的编译器。不是每一个编译器都会得出这样的结论:“好吧,你有
    int
    s称为
    i1
    i2
    i3
    i4
    ,它们都应用了相同的操作,所以让我们对它们进行SIMD!”
  • 工作组中的标量数据类型几乎肯定不会被矢量化。它们仍将并发执行(因为如果不是,那么我们为什么要首先编写GPGPU代码??),但编译器和运行时几乎肯定不会是并行的