理解OpenCL中的合并

理解OpenCL中的合并,opencl,Opencl,我试图理解凝聚记忆。经过一些研究,我了解到合并内存是为了确保线程访问顺序内存,以便它可以在一个事务中读取所有数据。这些数据可以被同一组中的其他线程重用 然而,当我看一个真实的例子时,我不知道为什么下面的函数合并不好: __kernel void mapSin( __global float* input, __global float* input, const unsigned int cout) { int x = get_global_id(0);

我试图理解凝聚记忆。经过一些研究,我了解到合并内存是为了确保线程访问顺序内存,以便它可以在一个事务中读取所有数据。这些数据可以被同一组中的其他线程重用

然而,当我看一个真实的例子时,我不知道为什么下面的函数合并不好:

__kernel void mapSin(
    __global float* input,
    __global float* input,
    const unsigned int cout)
{
    int x = get_global_id(0);
    int y = get_global_id(1);
    output[x * count + y] = sin(input[x * count + y]);
}

我猜想乘法
x*计数
会导致离散内存访问。我说得对吗?有什么方法可以改进此功能,从而实现更好的合并?

是的,您是对的,这是因为
x*count
导致每个工作项读取与其他相邻工作项不相邻的内存。内存中的宽读部分被使用(其余部分被丢弃,最终每个工作项都会被序列化)
x
是代码中“移动更快”的全局_id,因此请尝试将其设为id(1)并设为y id(0)(然后在内核排队的位置交换宽度和高度)。这将使
y
相邻工作项的id更改为1,这将使内存访问也相邻,这是获得合并内存访问的方式(一次宽读可以满足多个工作项;即并行读取)