OpenCL 内核中的组内同步,在本地内存上使用自旋锁

Posted

技术标签:

【中文标题】OpenCL 内核中的组内同步,在本地内存上使用自旋锁【英文标题】:Within-group synchronization in OpenCL kernel, which use spinlock on local memory 【发布时间】:2021-11-28 11:29:45 【问题描述】:

我正在尝试在 NVIDIA GPU 上运行以下代码,但每次都得到不同的结果。据我所知,问题不在于自旋锁本身(它正确地强制锁定本地内存中的变量),而在于atomicFunc 调用后的屏障损坏。我尝试使用 1 个大小为 256 的工作组运行此示例。该问题仅在 NVIDIA GPU 上观察到。

#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable

int baseFunc(private int x)

    return (x + 1);


int atomicFunc(__local int* localAccMutex, __local int* x)

    int oldValue;
    bool flag = 1;
    while (flag) 
        int old = atom_xchg(&localAccMutex[0], 1);
        if (old == 0) 
            oldValue = *x;
            *x = baseFunc(*x);
            atom_xchg(&localAccMutex[0], 0);
            flag = 0;
        ;
        barrier(CLK_LOCAL_MEM_FENCE);
    ;
    return oldValue;


__kernel void kernel(__global int* result)

    __local int localAcc[1];
    __local int localAccMutex[1];

    if (get_local_id(0) == 0) 
        localAccMutex[0] = 0;
    ;
    barrier(CLK_LOCAL_MEM_FENCE);

    if (get_local_id(0) == 0) 
        localAcc[0] = 0;
    ;
    barrier(CLK_LOCAL_MEM_FENCE);

    atomicFunc(localAccMutex, &localAcc[0]);
    // warps are ignoring this barrier
    barrier(CLK_LOCAL_MEM_FENCE);

    if (get_local_id(0) == 0) 
        result[0] = localAcc[0];
    ;

如果有任何帮助,我将不胜感激。

【问题讨论】:

【参考方案1】:

问题可能是while(flag) 内部的障碍。根据barrier规范:

这个函数必须是 工作组中的所有工作项遇到 执行内核。

如果屏障在循环内,则所有工作项都必须 为循环的每次迭代执行屏障 在允许任何人继续执行之前 越过障碍。

在将值更改为 1 后,您也无需运行 atom_xchg(&localAccMutex[0], 0)。您可以在每次迭代时翻转选中的值:

int atomicFunc(__local int* localAccMutex, __local int* x)

    int oldValue;
    int flip = 0;
    bool flag = 1;
    while (flag) 
        int old = atom_xchg(&localAccMutex[0], 1 - flip);
        if (old == flip) 
            oldValue = *x;
            *x = baseFunc(*x);
            flag = 0;
        
        flip = 1 - flip; // 0 -> 1; 1 -> 0
    
    return oldValue;

【讨论】:

以上是关于OpenCL 内核中的组内同步,在本地内存上使用自旋锁的主要内容,如果未能解决你的问题,请参考以下文章

OpenCL - 全局内存读取性能优于本地

如何在 OpenCL 中使用本地内存?

带有 OpenCL 的 Intel HD 6000 本地内存带宽 [关闭]

OpenCL 中的全局内存是不是连续

OpenCL 本地内存大小和计算单元数量

OpenCL 中的全局内存限制