Parallel processing 为什么原子操作只在HLSL计算着色器中的线程组内工作?

Parallel processing 为什么原子操作只在HLSL计算着色器中的线程组内工作?,parallel-processing,hlsl,compute-shader,Parallel Processing,Hlsl,Compute Shader,我有两个缓冲区,src和targetsrc是具有重复项的随机值(可能类似于{1,3,1,3,2,3,…})目标最初全部为零 我想做的是(在C++语法中): 但我想在HLSL计算着色器中执行此操作。由于src中存在重复项,因此可能存在数据争用。所以我实现了AtomicAdd操作: #define AtomicAdd(BUFFER, IDX, VALUE) \ keepWaiting = true;\ do {\ uint ov;\ InterlockedCompareExchang

我有两个缓冲区,
src
target
src
是具有重复项的随机值(可能类似于
{1,3,1,3,2,3,…}
)<代码>目标最初全部为零

<>我想做的是(在C++语法中):

但我想在HLSL计算着色器中执行此操作。由于
src
中存在重复项,因此可能存在数据争用。所以我实现了
AtomicAdd
操作:

#define AtomicAdd(BUFFER, IDX, VALUE) \
keepWaiting = true;\
do {\
    uint ov;\
    InterlockedCompareExchange(BUFFER##_Mutex[IDX], 0, 1, ov);\
    if (ov == 0) {\
        BUFFER[IDX] += VALUE;\
        BUFFER##_Mutex[IDX] = 0;\
        keepWaiting = false;\
    }\
} while (keepWaiting)
在仅包含一个组的计算着色器中,如:

// called by group number (1, 1, 1)
[numthreads(512, 1, 1)]
void kernel(uint3 id : SV_DispatchThreadID) {
    for (uint i = 0; i <= SrcSize / 512; i++) {
        uint idx = i * 512 + id.x;
        if (idx >= SrcSize) {
            return;
        }

        bool keepWaiting;

        uint srcValue = src[idx];

        AtomicAdd(Target, srcValue, 1);
    }
}
它不会产生正确的结果

所以我的问题是:为什么会发生这种情况?这两种内核的区别是什么

// called by group number (1, 1, 1)
[numthreads(512, 1, 1)]
void kernel(uint3 id : SV_DispatchThreadID) {
    for (uint i = 0; i <= SrcSize / 512; i++) {
        uint idx = i * 512 + id.x;
        if (idx >= SrcSize) {
            return;
        }

        bool keepWaiting;

        uint srcValue = src[idx];

        AtomicAdd(Target, srcValue, 1);
    }
}
// called by group numbers (X, 1, 1), X is a large number and X * 512 > SrcSize.
[numthreads(512, 1, 1)]
void kernel(uint3 id : SV_DispatchThreadID) {
    if (id.x >= SrcSize) {
        return;
    }

    bool keepWaiting;

    uint srcValue = src[idx];

    AtomicAdd(Target, srcValue, 1);
}