Performance 我应该创建多个OpenCL内核来避免条件语句吗?

Performance 我应该创建多个OpenCL内核来避免条件语句吗?,performance,cuda,opencl,nvidia,conditional-statements,Performance,Cuda,Opencl,Nvidia,Conditional Statements,在OpenCL中,我有一个需要对复杂和真实数据进行操作的内核。我可以在调用正确代码行的代码中放入一个条件语句来处理这个问题,或者我可以调用两个内核,然后将条件语句推送到调用代码中 这显然不利于可维护性,但对性能有意义吗?取决于条件的位置。首先是可读性代码,然后是性能代码,在您对它进行测量并发现它是一个问题之后 例如,kernel_for_RGB_image和kernel_for_ABGR_image似乎是一种合理的使用,不同的内核有效地展开一些深层的内部循环可能是一个更大的维护难题。如果只是一个

在OpenCL中,我有一个需要对复杂和真实数据进行操作的内核。我可以在调用正确代码行的代码中放入一个条件语句来处理这个问题,或者我可以调用两个内核,然后将条件语句推送到调用代码中


这显然不利于可维护性,但对性能有意义吗?

取决于条件的位置。首先是可读性代码,然后是性能代码,在您对它进行测量并发现它是一个问题之后


例如,kernel_for_RGB_image和kernel_for_ABGR_image似乎是一种合理的使用,不同的内核有效地展开一些深层的内部循环可能是一个更大的维护难题。

如果只是一个条件语句,根据我的经验,性能差异是完全可以忽略的,至少在NVidia硬件上是如此


基本上,只要所有(或大多数)工作项都遵循相同的代码路径,就可以了。由于所采用的代码路径取决于本例中的内核参数,因此所有工作项都遵循相同的路径。

我认为最好的方法是实际尝试并对两个变体进行基准测试。在某些情况下,编译多个条件块,即使只执行其中一个,也会导致性能下降。原因是GPRs(通用寄存器):编译器根据最坏的情况分配尽可能多的寄存器

我可以建议这样一种解决方案:使用单个内核函数,但使用编译时条件:

__kernel void work()
{
#if VAR
    // one code
#else
    // another code
#endif
}
然后,您需要在更改条件时重新编译内核,并将
true
/
false
设置为
VAR
。显然,对于编译器来说,它与两个内核没有什么不同,但是对于维护来说,如果这些内核的代码的一部分是相同的,可能会更好