"if conditions" 会影响 OpenCL 中内核执行的性能吗?

Do "if conditions" affect the performance of kernel execution in OpenCL?

我正在 运行 对图像进行过滤,我先执行垂直传递,然后执行水平传递。此任务的功能对于两个通道都是相同的,只是参数值发生了变化。我在循环中调用函数。为了向量化该函数中的操作,我必须为两次传递编写单独的函数调用。现在,循环对于水平和垂直通道是分开的。由于此更改,现在添加了 "if condition",我注意到即使计算是矢量化的,内核的执行时间也更长。我有几次 运行 代码,矢量化代码所用的平均时间比原始代码多。是因为代码中插入了"if condition"吗?

原码

global int* a;

for(int i = 0; i < 4; i++)
{
    filter(a + i, b, c);
}

修改后的代码

global int* a;

if(offset == 1)
for(int i = 0; i < 4; i++)
{
    filter_vertical(a + i, b, c);
}
else
    filter_horizontal(a, b, c);

你是说 offset == 1 吗?

if(offset = 1)

将 1 分配给偏移量,这是每个线程的 "extra latency"。这比原来慢。但除此之外,"if" 根据组合在一起的分支 "taken" 或 "not taken" 的模式向上或向下更改性能,因为某些架构(如 GPU SIMD)会填充气泡以并行 SIMD 管道,当这些与相邻管道的分支选项不同,因此它们留给其他波前线程的占用机会,如果它们不能填充 neiter,则性能会降低。

为了更好的表现,

for(int i = 0; i < 4; i++)
{
    filter_vertical(a + i, b, c);
}

    filter_vertical(a , b, c);
    filter_vertical(a + 1, b, c);
    filter_vertical(a + 2, b, c);
    filter_vertical(a + 3, b, c);

需要更多的指令缓存,但需要更少的分支,需要更少的内存使用和更少的周期。

如果可以将 offset == 1 个案例组合在一起,如果内存访问操作不影响它会更快。