我有一个这样的内核
kernel void k1(global int * a, global int * b, global int * c){
int i = get_local_id(0);
global int* ptr;
if (i==0) ptr = &a[0];
if (i==1) ptr = &b[0];
if (i==2) ptr = &c[0];
if (i>2) return;
ptr[0]++;
}
我的问题是,ptr[0]++ 行会在访问内存时创建分支吗?或者与 a[0]++;b[0]++;c[0]++;在同一工作项内。
感谢您的宝贵时间。
最佳答案
不,这不会创建分支,但至少在某些工作组中会破坏合并的内存访问。
您还可以用三元运算符 (condition ? true_action : false_action
) 完全替换 if(i==0) ptr = &a[0];
等或通过位掩码。如此简单的 if 语句和三元运算符最有可能转换为无分支汇编。如果没有保护子句 (if(i>2) return;
),则整个代码是无分支的。
虽然没有分支,但更重要的是,特别是使用比您拥有的更复杂的指针算术(例如,当查找表确定指针值时),告诉应该访问哪个内存位置的算术将破坏某些情况下的合并内存访问工作组,与简单的分支本身相比,这可能会导致更慢的速度(尽管分支也不能解决未对齐的内存访问问题)。
在某些应用程序中,以合并方式加载更多全局内存甚至可能比减少全局内存访问但在进程中破坏合并更快。
关于optimization - Opencl,使用指向不同本地内存的全局指针会创建分支吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71231781/