相邻工作项的OpenCL向量化

时间:2016-12-08 22:19:11

标签: opencl gpu

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

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

我在“clBuildProgram”之后查看了Nvidia ptx文件,我仍然看到标量IR,但我不确定Intel或AMD。

1 个答案:

答案 0 :(得分:2)

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

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

这取决于您的数据布局和内核逻辑的准确程度,以及(可能是在线)编译器选择优化代码的程度。它在很大程度上取决于实际的硬件,但我马上就会谈到它。

  • 矢量数据类型(如float4int4float8等)最容易进行矢量化,甚至可能甚至不需要优化传递来执行此操作,因为代码非常明确地说“这些数据都属于一起,并且(可能)会对它应用相同的操作,所以如果你有硬件可以做到这一点 (但是我下面将解释,这是一个相当大的'if') 让我们使用这些类型的SIMD说明!“
  • 除非你有一个非常聪明的编译器,否则标量数据类型可能不会被优化。不是每个编译器都能解决“嗯,你有inti1i2i3i4,他们'所有人都应用了相同的操作,所以让我们SIMD吧!“
  • 工作组中的标量数据类型几乎肯定不会被矢量化。它们仍将同时执行(因为如果没有,那么为什么我们甚至首先编写GPGPU代码?)但编译器和运行时几乎肯定无法围绕它们进行优化。
  • 编辑:正如所指出的,有Compiler Tricks可以使这种矢量化成为可能。但值得记住的是,这些技巧发生在编译时,而不是在运行时,这意味着它高度依赖于代码的编写方式,以及使用哪个编译器(以及哪些优化标志,如果存在)来编译内核代码。

所有这一切最重要的是要记住,所有这些都取决于卡的硬件功能。至少在消费级计算卡(翻译为:GPU)中,硬件工程师实际上并没有对其矢量化功能进行重大升级,事实上,他们经常选择削减矢量化以专注于制造更小的核心,然后他们可以堆叠更多的芯片。例如,拥有一个具有128个内核的卡,每个都可以执行256位SIMD指令,这是一个很好的奢侈品,但通常情况下,拥有一个没有(或可以'的微小内核的卡要容易得多) t)处理SIMD指令,并简单地堆叠如此多的内核(如NVidia最近的发布,超过4k),它们可以简单地并行运行,执行相同的工作(通常更快),而不依赖于程序员编写明确的SIMD指令。 / p>

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